我有两张表A
和B
都非常大。我正在尝试进行这样的查询,但是花费几分钟才能完成。表格A
的索引为name
,而表格B
的索引为other_name
。
SELECT * FROM A
LEFT JOIN B ON A.id = B.id
WHERE A.name = 'text' OR B.other_name = 'text'
如果我使用UNION执行单个条件,则查询会按预期运行得非常快。
SELECT * FROM A
LEFT JOIN B ON A.id = B.id
WHERE A.name = 'text'
UNION
SELECT * FROM A
LEFT JOIN B ON A.id = B.id
WHERE B.other_name = 'text'
我不明白为什么第一次比第二次跑得慢得多。
答案 0 :(得分:4)
直接从dev.mysql:
添加到Gordon Linoff的回答最小化WHERE子句中的OR关键字。如果没有索引有助于在OR的两侧定位值,则任何行都可能是结果集的一部分,因此必须测试所有行,这需要全表扫描。如果您有一个索引有助于优化OR查询的一侧,而另一个索引有助于优化另一侧,请使用UNION运算符运行单独的快速查询并在之后合并结果。
答案 1 :(得分:3)
在第二个查询中,由于where
子句,第二个连接将转为内连接:
SELECT *
FROM A LEFT JOIN
B
ON A.id = B.id
WHERE A.name = 'text'
UNION
SELECT *
FROM A JOIN
B
ON A.id = B.id
WHERE B.other_name = 'text';
此查询可以在A(name)
和B(other_name)
中使用这两个部分中的索引。
第一个查询只能使用一个索引。但是,它既没有索引完全满足查询,所以它最终处理没有索引的查询。