mysql - SQL 性能 UNION 与 OR

标签 mysql sql performance union

我刚刚阅读了一篇优化文章的一部分,并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:

enter image description here

使用UNION:

enter image description here

这不是说 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/

相关文章:

Mysql获取当前计数直到结果

php - 多个表上的 Codeigniter/PHP 外部 JOIN 语法

PHP MySQL 表链接

mysql - 我可以在没有 union 子句的情况下重写这个查询吗

javascript - 带速度控制的图像动画

php - 将包含 CSV 的 MYSQL 变量插入表中

mysql - 从 DOUBLE (15,2) 转换为 DECIMAL (15,2)

php - 如何防止 PHP 中的 SQL 注入(inject)?

java - O(1) 中的 value.contains(object) 的高效 java 映射?

php - 拥有大量数据库时遇到问题?