SQL Performance UNION与OR

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


当使用SQL代替using语句OR有UNION:


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

至:


select username from users where company = ‘bbc’ union

select username from users where company = ‘itv’;

从快速EXPLAIN:


使用OR:

使用UNION:

没有这意味着UNION确实在双工作?


尽管我赞赏UNION某些RDBMS和某些表模式的性能可能更高,但这在作者看来并不是绝对正确的。


我错了吗?


慕码人8056858
浏览 596回答 3
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' unionselect username from users where city = 'London';现在,每个子查询都可以使用索引进行搜索,并且子查询的结果由组合UNION。一位匿名用户对我的回答提出了修改建议,但主持人拒绝了该修改。它应该是评论,而不是编辑。提议的编辑声称,UNION必须对结果集进行排序以消除重复的行。这会使查询运行速度变慢,因此索引优化是一项艰巨的任务。我的回答是,索引有助于在UNION发生之前将结果集减少为少量的行。实际上,UNION确实消除了重复项,但是这样做只需要对小的结果集进行排序。在某些情况下,WHERE子句与表的大部分匹配,并且在UNION期间进行排序与进行表扫描一样昂贵。但是,通过索引搜索减少结果集的情况更为常见,因此排序的成本要比表扫描的成本低得多。差异取决于表中的数据以及要搜索的术语。确定给定查询的最佳解决方案的唯一方法是尝试在MySQL查询探查器中使用这两种方法并比较它们的性能。

梵蒂冈之花

这些不是相同的查询。我对MySQL没有太多的经验,所以我不确定查询优化器会做什么或不做什么,但是这是我一般背景下的想法(主要是ms sql server)。通常,查询分析器可以采用上述两个查询,并根据它们制定完全相同的计划(如果它们相同),所以没关系。我怀疑这些查询之间没有性能差异(等效)select distinct username from users where company = ‘bbc’ or company = ‘itv’;和select username from users where company = ‘bbc’ unionselect username from users where company = ‘itv’;现在的问题是,以下查询之间是否会有区别,而我实际上并不知道这些区别,但是我怀疑优化程序会使它更像第一个查询select username from users where company = ‘bbc’ or company = ‘itv’;和select username from users where company = ‘bbc’ union allselect username from users where company = ‘itv’;

暮色呼如

这取决于优化器根据数据,索引,软件版本等的大小来完成的工作。我猜想使用OR会给优化器提供更高的效率,因为所有内容都在一个逻辑语句中。同样,UNION也有一些开销,因为它创建了一个重置集(没有重复项)。在UNION每个语句应该执行很快,如果公司被索引...不知道它会真的做双倍的工作。底线除非您确实有迫切需要从查询中挤出每一点速度,否则最好采用能最好地传达您意图的表格。更新资料我也想提到IN。我相信以下查询将比OR提供更好的性能(这也是我更喜欢的形式):select username from users where company in ('bbc', 'itv');
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

MySQL