我刚刚阅读了一篇优化文章的一部分,并segfaulted对以下语句:
When using SQL replace statements using
OR
with aUNION
:select username from users where company = ‘bbc’ or company = ‘itv’;
to:
select username from users where company = ‘bbc’ union select username from users where company = ‘itv’;
快速EXPLAIN
:
使用 OR
:
使用UNION
:
这不是说 UNION
做了双倍的工作吗?
虽然我很欣赏 UNION
对于某些 RDBMS 和某些表模式可能会更高效,但正如作者建议的那样,绝对正确。
问题
我错了吗?
最佳答案
要么你阅读的文章使用了一个不好的例子,要么你误解了他们的观点。
select username from users where company = 'bbc' or company = 'itv';
这相当于:
select username from users where company IN ('bbc', 'itv');
MySQL 可以使用 company
上的索引来进行此查询。无需执行任何 UNION。
更棘手的情况是您有一个涉及两个不同列的OR
条件。
select username from users where company = 'bbc' or city = 'London';
假设 company
上有一个索引,city
上有一个单独的索引。鉴于 MySQL 通常在给定查询中每个表只使用一个索引,它应该使用哪个索引?如果它使用 company
上的索引,它仍然需要进行表扫描才能找到 city
是伦敦的行。如果它使用 city
上的索引,则必须对 company
为 bbc 的行进行表扫描。
UNION
解决方案适用于这种情况。
select username from users where company = 'bbc'
union
select username from users where city = 'London';
现在每个子查询都可以使用索引进行搜索,子查询的结果由UNION
组合。
一位匿名用户提议对我上面的回答进行修改,但版主拒绝了该修改。它应该是评论,而不是编辑。提议的编辑声称 UNION 必须对结果集进行排序以消除重复行。这使得查询运行速度变慢,因此索引优化是一种清洗。
我的回答是索引有助于在 UNION 发生之前将结果集减少到少数行。 UNION 实际上确实消除了重复,但要做到这一点,它只需要对小的结果集进行排序。在某些情况下,WHERE 子句与表的很大一部分匹配,并且在 UNION 期间进行排序与简单地进行表扫描一样昂贵。但更常见的是通过索引搜索来减少结果集,因此排序比表扫描成本低得多。
差异取决于表中的数据以及正在搜索的字词。确定给定查询的最佳解决方案的唯一方法是尝试 the MySQL query profiler 中的两种方法。并比较他们的表现。
关于mysql - SQL 性能 UNION 与 OR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13750475/