mysql - SQL 性能 UNION 与 OR

我刚刚阅读了一篇优化文章的一部分,并segfaulted对以下语句:

When using SQL replace statements using OR with a UNION:

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 中的两种方法。并比较他们的表现。

https://stackoverflow.com/questions/13750475/

相关文章:

mysql - 遇到需要满足多个条件的 MySQL Join 问题

mysql - MySQL 是否索引 NULL 值?

MySQL - 条件外键约束

sql - 单数还是复数数据库表名?

mysql - 如何解决 "Error: MySQL shutdown unexpectedly"?

mysql - 错误 : select command denied to user '

java - 如何解决无法加载身份验证插件 'caching_sha2_password' 问题

python - MySQL:从查询中获取列名或别名

mysql - 允许所有远程连接,MySQL

mysql - 如何在 Sequel Pro 中执行查询?