我有两个表,其中的〜1M行由其ID索引。
休闲查询...
SELECT t.* FROM transactions t
INNER JOIN integration it ON it.id_trans = t.id_trans
WHERE t.id_trans = '5440073'
OR it.id_integration = '439580587'
此查询大约需要30秒。但是...
SELECT ... WHERE t.id_trans = '5440073'
花费不到100毫秒的时间,并且
SELECT ... WHERE it.id_integration = '439580587'
也花费不到100毫秒。偶
SELECT ... WHERE t.id_trans = '5440073'
UNION
SELECT ... WHERE it.id_integration = '439580587'
花费不到100毫秒
即使部分很快,OR
子句为什么仍要花费很多时间?
答案 0 :(得分:1)
为什么OR
这么慢,但是UNION
这么快?
您了解为什么UNION
快吗?因为它可以使用两个单独的索引来发挥良好的优势,并从UNION
的每个部分收集一些结果行,然后将结果组合在一起。
但是OR
为什么不能这样做?简而言之,Optimizer不够聪明,无法尝试该角度。
在您的情况下,测试位于不同的表中;对于EXPLAIN SELECT ...
的两个部分,这将导致根本不同的查询计划(请参见UNION
)。每个都可以很好地优化,所以每个都很快。
假设每个部分仅传递几行,则UNION
的后续开销很小-即收集两行小集,对它们进行重复处理(如果您使用UNION DISTINCT
而不是{{ 1}}),并提供结果。
与此同时,UNION ALL
查询可以有效地收集两个表的所有组合,然后根据OR
的两个部分过滤出 then 。中间阶段可能涉及一个巨大的临时表,只是要扔掉大多数行。
(inflate-deflate的另一个示例是OR
+ JOINs
。解决方法不同。)
答案 1 :(得分:0)
我建议使用http://
编写查询:
UNION ALL
注意:如果id是真正的数字(而不是字符串),请删除单引号。混合类型有时会混淆优化器并阻止使用索引。