【问题标题】:A Complex query into Union mysql multiple times - Optimizer多次对 Union mysql 进行复杂查询 - 优化器
【发布时间】:2018-05-19 10:45:15
【问题描述】:

我想在 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 个组部分中,每个部分的顺序不同

【问题讨论】:

  • 显然执行了 3 次 .. 你在不同的列上使用 order by 并且为了获得结果,所有 3 个子查询都被完整地执行了
  • 子查询一模一样!所以 T 别名是相同的,第二次我在不同的列中订购我没有问题。我只问子子查询
  • 3 个子查询已完全重新执行 .. 动态表未重用 .. 对于 db 引擎,3 个查询甚至是 3 个新查询 ..如果您想要更好的性能,请确保您有适当的索引您用于过滤的列
  • 那么我该怎么做才能避免3次执行?
  • 如果您想要基于不同顺序的 3 组不同的 10 行...您无法避免 3 查询...是 SQL .. 不是魔术 .. 不可能获得 3不同的事物形成同一个查询

标签: mysql optimization subquery union


【解决方案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然后 JOINAB 一起一次

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

【讨论】:

    猜你喜欢
    • 2019-06-09
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多