[英]Why are UNION queries so slow in MySQL?
当我优化我的 2 个单个查询以在不到 0.02 秒内运行,然后UNION
它们时,结果查询需要超过 1 秒才能运行。 此外, UNION ALL
比UNION DISTINCT
花费的时间更长。
我认为允许重复会使查询运行得更快而不是更慢。 我真的只是更好地分别运行 2 个查询吗? 我更喜欢使用UNION
。
作为一个简单的例子,如果我这样做
SELECT name FROM t1 WHERE field1 = true
需要 0.001 秒
如果我这样做
SELECT name FROM t1 WHERE field1 = false
它需要 0.1 秒。
如果我然后跑
SELECT name FROM t1 WHERE field1 = true
UNION ALL
SELECT name FROM t1 WHERE field1 = false
它需要超过 1 秒。
当我优化我的 2 个单个查询以在不到 0.02 秒的时间内运行,然后将它们合并时,结果查询需要超过 1 秒才能运行。
您的查询是否包括ORDER BY … LIMIT
子句?
如果将ORDER BY … LIMIT
放在UNION
,它将应用于整个UNION
,并且在这种情况下不能使用索引。
如果id
是主键,则此查询将是即时的:
SELECT *
FROM table
ORDER BY id
LIMIT 1
,但这个不会:
SELECT *
FROM table
UNION ALL
SELECT *
FROM table
ORDER BY id
LIMIT 1
此外,
UNION ALL
比UNION DISTINCT
花费的时间更长。 我认为允许重复会使查询运行得更快而不是更慢。
这似乎也是由于ORDER BY
。 对较小的集合进行排序比对较大的集合进行排序要快。
我真的只是更好地分别运行 2 个查询吗? 我更喜欢使用
UNION
您需要对结果集进行排序吗?
如果没有,只需去掉最后的ORDER BY
。
关于UNION
UNION DISTINCT
(在默认UNION
)必然是慢,因为它必须收集两个结果,然后去重复。 但是,由于退回给客户的数量较少,因此可能会有一些补偿。UNIONs
涉及一个临时表来收集结果,因此UNION
必然比两个单独的SELECTs
慢。 最近,(MySQL 5.7,MariaDB 10.1)对UNION ALL
一些情况进行了改进,将数据从一个SELECT
直接传送到客户端,然后再传送其他。SELECT .. UNION SELECT .. ORDER BY ..
等价于(SELECT .. UNION SELECT ..) ORDER BY ..
-- 这个(SELECT ..) UNION (SELECT .. ORDER BY ..)
-- 不是这个SELECT
周围使用括号。ORDER BY
)可能需要额外的时间来处理它所附加的任何(选择或联合)。 不太可能花更少的时间。 简单地说,优化器的目标是做任何最快的事情,这可能会被排序。OR
的单个SELECT
可以通过将其转换为UNION
来加速,从而允许使用两个索引。关于测试:
SQL_NO_CACHE
避免这种SQL_NO_CACHE
。WHERE flag = true (or false)
有几种情况: flag
是否被索引? flag
几乎总是这些值之一吗? 在这种情况下,将使用索引,并且可能比其他情况更快。猜测:由于您查询具有 2 个联合的一个表,因此 mysql 可能难以决定该表的锁定策略,或者它尝试进行一些缓存,这在这里不起作用,因为您查询不相交的集合,尝试多线程访问(非常合理)但遇到一些锁定/并发/文件搜索问题..
工会通常也可能采用更高的安全设置,因为这两个选择必须一致。 如果您将它们放入单独的事务中,则它们不会。
实验:制作表格的副本并将它们合并。 如果我是对的,它应该更快。
可能的解决方案:将单个文件拆分为多个文件,以实现更好的并发策略。 这不会/不应该有助于解决锁定问题,但排除了数据库中的多线程/搜索问题。
了解您使用的存储引擎会很有用。
好吧,只是我的 2 美分。 现在无法在这里测试。
UNION ALL 比 UNION 快,因为普通的 UNION 期望在两个连接的数据集中有需要删除的重复项。 如果您可以(通过内部 WHERE 子句)确保没有重复项,那么最好使用 UNION ALL 并让数据库引擎优化内部选择。
对分组结果的结果使用 WHERE 子句成本太高,因为您操作的内部结果比您需要的要多。 此外,无法处理数据库引擎的优化——结果没有任何共同点。
查看此链接了解详情https://dzone.com/articles/performance-tip-for-tuning-sql-with-union
是不是您测量的是响应时间而不是检索所有数据的时间?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.