首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL Performance vs OR

SQL Performance vs OR
EN

Stack Overflow用户
提问于 2012-12-06 18:51:39
回答 6查看 57.1K关注 0票数 84

我刚刚阅读了一篇优化文章的一部分,并对以下语句进行了分段错误:

当使用使用OR的SQL语句时,使用一个UNION: 从公司=‘bbc’或公司=‘itv’的用户中选择用户名; 至: 从公司=‘bbc’联盟的用户中选择用户名,从公司=‘itv’的用户中选择用户名;

从快速的EXPLAIN

使用OR

使用UNION

这不意味着UNION的工作量增加了一倍吗

虽然我理解UNION对于某些RDBMSes和某些表模式可能具有更高的性能,但正如作者所建议的那样,这并不是绝对正确的。

问题

我说错了吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-12-13 18:35:40

要么你读的文章引用了一个糟糕的例子,要么你曲解了他们的观点。

代码语言:javascript
复制
select username from users where company = 'bbc' or company = 'itv';

这相当于:

代码语言:javascript
复制
select username from users where company IN ('bbc', 'itv');

对于这个查询,MySQL可以在company上使用索引。没有必要做任何工会。

更棘手的情况是,您有一个涉及两个不同列的OR条件。

代码语言:javascript
复制
select username from users where company = 'bbc' or city = 'London';

假设company上有一个索引,city上有一个单独的索引。假设MySQL通常在给定的查询中每个表只使用一个索引,那么它应该使用哪个索引?如果它在company上使用索引,它仍然需要做一个表扫描来查找city位于伦敦的行。如果它在city上使用索引,就必须对company所在的行进行表扫描。

UNION解决方案是针对这种情况的。

代码语言:javascript
复制
select username from users where company = 'bbc' 
union
select username from users where city = 'London';

现在,每个子查询都可以使用索引进行搜索,子查询的结果由UNION组合。

一个匿名用户建议对我上面的答案进行编辑,但是版主拒绝了编辑。它应该是一个评论,而不是编辑。建议编辑的声明是,UNION必须对结果集进行排序,以消除重复的行。这使得查询运行得更慢,因此索引优化就是一次清洗。

我的反应是,索引有助于在UNION发生之前将结果集减少到少量行。UNION实际上消除了重复,但要做到这一点,它只需对小的结果集进行排序。在某些情况下,where子句与表的很大一部分匹配,而在UNION中进行排序就像简单地进行表扫描一样昂贵。但是,通过索引搜索来减少结果集是比较常见的,所以排序比表扫描成本低得多。

差异取决于表中的数据和正在搜索的术语。确定给定查询的最佳解决方案的唯一方法是在MySQL查询分析器中尝试这两种方法并比较它们的性能。

票数 143
EN

Stack Overflow用户

发布于 2012-12-06 19:07:19

这些不是相同的查询。

我对MySQL没有太多的经验,所以我不确定查询优化器做什么或不做什么,但是下面是我的一般背景(主要是MySQL)的想法。

通常情况下,查询分析器可以接受上述两个查询,并对它们制定完全相同的计划(如果它们是相同的),所以这并不重要。我怀疑这些查询(它们是等价的)之间没有性能差异。

代码语言:javascript
复制
select distinct username from users where company = ‘bbc’ or company = ‘itv’;

代码语言:javascript
复制
select username from users where company = ‘bbc’ 
union
select username from users where company = ‘itv’;

现在的问题是,下面的查询(实际上我不知道)之间是否有区别,但我怀疑优化器会使它更像第一个查询

代码语言:javascript
复制
select username from users where company = ‘bbc’ or company = ‘itv’;

代码语言:javascript
复制
select username from users where company = ‘bbc’ 
union all
select username from users where company = ‘itv’;
票数 5
EN

Stack Overflow用户

发布于 2012-12-06 19:07:25

这取决于优化器根据数据、索引、软件版本等的大小所做的事情。

我猜想使用OR会给优化器找到一些效率的更好机会,因为所有东西都在一个逻辑语句中。

同时,UNION也有一些开销,因为它创建了一个重置集(没有重复设置)。如果公司被编入索引,联盟中的每个语句都应该执行得很快.不确定它是否真的能做两倍的工作。

底线

除非你真的有迫切的需要挤出你的查询的每一点速度,它可能更好地与形式,最好是沟通你的意图.OR

更新

我也想提一下。我相信以下查询将提供比OR更好的性能(这也是我更喜欢的形式):

select username from users where company in ('bbc', 'itv');

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13750475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档