一个复杂的查询到Union mysql多次 - 优化器

时间:2018-05-05 18:57:04

标签: mysql optimization subquery union

我想在UNION中多次使用相同的子查询。这个子查询耗费时间,我认为使用它很多次可能会增加执行的总时间。

例如

(SELECT * FROM (SELECT * FROM A INNER JOIN B ... AND SOME COMPLEX WHERE CONDITIONS) as T ORDER BY column1 DESC LIMIT 10)
UNION
(SELECT * FROM (SELECT * FROM A INNER JOIN B ... AND SOME COMPLEX WHERE CONDITIONS) as T ORDER BY column2 DESC LIMIT 10)
UNION
(SELECT * FROM (SELECT * FROM A INNER JOIN B ... AND SOME COMPLEX WHERE CONDITIONS) as T ORDER BY column3 DESC LIMIT 10)

(SELECT * FROM A INNER JOIN B ... AND SOME COMPLEX WHERE CONDITIONS)执行了3次吗?

如果mysql足够聪明,内部子查询将只执行一次,所以我不需要任何优化,但如果不是,我必须使用其他东西来优化它(比如使用临时表,但我想避免它)

我是否必须通过其他语法优化此查询?有什么建议吗?

在实践中,我想从大型记录中过滤一些数据,并在3个小组部分中获取其中一些,每个部分的顺序不同

1 个答案:

答案 0 :(得分:1)

计划A:

TEMPORARY TABLE不能多次引用。因此,在完成后构建一个永久表并DROP。 (如果您可能有多个连接执行相同的操作,那么确保您不使用相同的表名将是一件麻烦事。)

B计划:

使用MySQL 8.0,你可以做到

WITH T AS ( SELECT ... )
SELECT ... FROM T ORDER BY col1
UNION ...

计划C:

如果可以这样做:

SELECT id FROM A
     ORDER BY col1 LIMIT 10

您可以将其用作

中的“派生”表格
(SELECT * FROM A INNER JOIN B ... AND SOME COMPLEX WHERE CONDITIONS)

这样的东西
SELECT A.*, B.*
    FROM ( SELECT id FROM A
               ORDER BY col1 LIMIT 10 ) AS x1
    JOIN A  USING(id)
    JOIN B ... AND SOME COMPLEX WHERE CONDITIONS

同样对于其他两个SELECTs,然后UNION他们在一起。

更好的是,UNION将3组ids然后 JOIN合并到AB 一旦

这个可能具有处理更少行的优势。