我刚刚阅读了优化文章的一部分,并且对以下声明进行了segfaulted:
使用 SQL 时,将使用
的语句替换为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 和某些表模式可能会更高效,但这并不像作者建议的那样“绝对正确”。
问题
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
组合在一起。
我对 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’;
我猜想使用 OR 会让优化器有更好的机会找到一些效率,因为一切都在一个逻辑语句中。
此外,UNION 有一些开销,因为它创建了一个重置
set(无重复项)。 如果 company 被索引的话,UNION 中的每条语句应该会很快执行...不确定它是否真的会做 double 的工作。 底线
更新
select username from users where company in ('bbc', 'itv');
13.8699
秒
检查行的主要选择类型 -247685
使用 OR 时 - 查询花费了0.0126
秒并且检查了主要行 选择类型 -
MySQL 使用一个索引进行查询,因此当我们使用495371
or
时,MySQL 使用一个列索引并扫描整个表以查找另一列
另一部分工会同样的工作可以进行2次这就是为什么 or 比 union 更快
union
或
union all
版本将对用户表进行两次全表扫描。or
版本在实践中要好得多,因为它只会扫描表一次。如果可用的话,它也只会使用一次索引。
对于任何数据库和任何情况,原始声明似乎都是错误的。
这通常取决于表的结构和需求,但在大型表中,联合给了我更好的结果。