在大多数情况下,当我尝试删除OR条件并用UNION(分别保存每个条件)替换它们时,它表现得更好,因为查询的那些部分可以再次索引。
当这个“技巧”停止有用时,是否有经验法则(可能还有一些支持它的文档)?它对2 OR条件有用吗? 10 OR条件?随着UNION数量的增加,UNION的不同部分可能会有自己的开销。
你对此有什么经验法则?
转型的一个小例子:
SELECT
a, b
FROM
tbl
WHERE
a = 1 OR b = 2
转换为:
(SELECT
tbl.a, tbl.b
FROM
tbl
WHERE
tbl.b = 2)
UNION DISTINCT
(SELECT
tbl.a, tbl.b
FROM
tbl
WHERE
tbl.a = 1)
答案 0 :(得分:1)
我建议没有有用的经验法则(RoT)。这就是为什么......
正如您所暗示的,更多UNIONs
意味着工作更慢,而更多ORs
则不会(至少不是很多)。联盟的SELECTs
代价很高,因为它们是分开的。我估计UNION
N SELECTs
需要大约N + 1或N + 2个时间单位,其中一个索引SELECT
占用1个单位时间。相比之下,多个ORs
几乎不会减慢查询速度,因为获取表的所有行是代价高昂的部分。
SELECT
的每个UNION
的运行速度取决于索引的好坏以及获取的行数。这可能会有很大差异。 (因此,很难设计出RoT。)
UNION
首先生成一个临时表,每个SELECT
添加它找到的行。这是一些开销。在较新的版本(5.7.3 / MariaDB 10.1)中,可以避免临时表的情况有限。 (这消除了假设的+1或+2,从而增加了设计RoT的复杂性。)
如果是UNION DISTINCT
(默认值)而不是UNION ALL
,则需要进行重复数据删除传递,可能涉及临时表的排序。注意:这意味着即使是新版本也无法避免临时表。 UNION DISTINCT
正好模仿OR
,但你可能知道ALL
会给出相同的答案。