在InnerJoin中重用mysql子查询

问题描述 投票:0回答:3

我正在尝试优化查询,试图避免重复用“COMPLEX QUERY”指示的查询,该查询使用了两次,并且两次都有相同的结果。

原始查询

SELECT news.* 
FROM   news 
   INNER JOIN((SELECT myposter 
               FROM   (SELECT **COMPLEX QUERY**)) 
              UNION 
              (SELECT myposter 
               FROM   `profiles_old` prof2 
               WHERE  prof2.profile_id NOT IN (SELECT **COMPLEX QUERY**))) r 
           ON news.profile = r.p 

我想知道这样的事情是否可能:

SELECT news.* 
FROM   (SELECT **COMPLEX QUERY**) complexQuery, 
   news 
   INNER JOIN ((SELECT myposter 
                FROM   complexquery) 
               UNION 
               (SELECT myposter 
                FROM   `profiles_old` prof2 
                WHERE  prof2. profile NOT IN (SELECT myposter 
                                              FROM complexQuery))) r 
           ON news. profile = r.p 

Mysql 是否对该类型的查询进行某种缓存?

mysql sql performance database-performance query-performance
3个回答
5
投票

你的问题的直接答案是“不”。 MySQL不支持你想要的。 你真正想要的是

with
声明。 很棒的声明! 如果需要,请使用不同的数据库。 唉。

我确实认为你可以做到这一点,尽管方法与你正在做的有很大不同。

逻辑是从复杂查询中获取

myposter
的所有值,并从
myposter
中获取
profiles_old
的所有值,其中相应的
profile_id
不在复杂查询中。

您可以使用

union all
和聚合来做到这一点。 只关注内部子查询:

select (case when max(which = 'cq') = 1 then myposter
             when max(which = 'po') = 1 and max(which = 'cq') = 0 then id2
       ) as myposter
from (select myposter, myposter as id2, 'cq' as which
      from (select **complex query**) cq
      union all
      select profile_id, myposter, 'po' as which
      from profiles_old
     ) t
group by myposter;

剩下的只是将其合并到您的整体查询中。


0
投票

我已经详细了解了要求,并以不同的方式给出了建议:

/* 创建临时表(最好使用内存存储引擎,但不是强制的): */

MYSQL> 创建临时表 tmp_intermediate_table engine=内存选择 COMPLEX QUERY;

然后,在当前用户会话中运行的查询中引用 tmp_intermediate_table 表。


0
投票

2024 年回到这里,自从上次响应

with
子句出现在 MySQL 中。根据文档你可以这样使用它:

WITH
  cte1 AS (SELECT a, b FROM table1),
  cte2 AS (SELECT c, d FROM table2)
SELECT b, d FROM cte1 JOIN cte2
WHERE cte1.a = cte2.c;
© www.soinside.com 2019 - 2024. All rights reserved.