为了账号安全,请及时绑定邮箱和手机立即绑定

SQL Performance UNION与OR

SQL Performance UNION与OR

慕码人8056858 2019-11-13 13:58:57
我刚刚阅读了优化文章的一部分,并对以下语句进行了细分:当使用SQL代替using语句OR有UNION:select username from users where company = ‘bbc’ or company = ‘itv’;至:select username from users where company = ‘bbc’ unionselect username from users where company = ‘itv’;从快速EXPLAIN:使用OR:使用UNION:没有这意味着UNION确实在双工作?尽管我赞赏UNION某些RDBMS和某些表模式的性能可能更高,但这在作者看来并不是绝对正确的。题我错了吗?
查看完整描述

3 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

您阅读的文章使用了一个错误的例子,或者您误解了他们的观点。


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通常在给定查询中每个表只使用一个索引,应该使用哪个索引?如果它使用on上的索引company,则仍必须进行表扫描以查找city伦敦所在的行。如果使用on上的索引city,则必须对companybbc 所在的行进行表扫描。


该UNION解决方案是对于这种类型的箱子。


select username from users where company = 'bbc' 

union

select username from users where city = 'London';

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


一位匿名用户对我的回答提出了修改建议,但主持人拒绝了该修改。它应该是评论,而不是编辑。提议的编辑声称,UNION必须对结果集进行排序以消除重复的行。这会使查询运行速度变慢,因此索引优化是一项艰巨的任务。


我的回答是,索引有助于在UNION发生之前将结果集减少为少量的行。实际上,UNION确实消除了重复项,但是这样做只需要对小的结果集进行排序。在某些情况下,WHERE子句与表的大部分匹配,并且在UNION期间进行排序与进行表扫描一样昂贵。但是,通过索引搜索减少结果集的情况更为常见,因此排序的成本要比表扫描的成本低得多。


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


查看完整回答
反对 回复 2019-11-13
?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

这些不是相同的查询。


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


通常,查询分析器可以采用上述两个查询,并根据它们制定完全相同的计划(如果它们相同),所以没关系。我怀疑这些查询之间没有性能差异(等效)


select distinct username from users where company = ‘bbc’ or company = ‘itv’;


select username from users where company = ‘bbc’ 

union

select username from users where company = ‘itv’;

现在的问题是,以下查询之间是否会有区别,而我实际上并不知道这些区别,但是我怀疑优化程序会使它更像第一个查询


select username from users where company = ‘bbc’ or company = ‘itv’;


select username from users where company = ‘bbc’ 

union all

select username from users where company = ‘itv’;


查看完整回答
反对 回复 2019-11-13
?
暮色呼如

TA贡献1853条经验 获得超9个赞

这取决于优化器根据数据,索引,软件版本等的大小来完成的工作。


我猜想使用OR会给优化器提供更高的效率,因为所有内容都在一个逻辑语句中。


同样,UNION也有一些开销,因为它创建了一个重置集(没有重复项)。在UNION每个语句应该执行很快,如果公司被索引...不知道它会真的做双倍的工作。


底线

除非您确实有迫切需要从查询中挤出每一点速度,否则最好采用能最好地传达您意图的表格。


更新资料

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


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


查看完整回答
反对 回复 2019-11-13
  • 3 回答
  • 0 关注
  • 592 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信