在SQL优化相关资料中,通常可以看到一个建议:用UNION来代替OR
举例
采用 OR 语句:
SELECT * FROM a, b WHERE a.p = b.q or a.x = b.y;
采用 UNION 语句,返回的结果同上面的一样,但是速度要快些:
SELECT * FROM a, b WHERE a.p = b.q
UNION
SELECT * FROM a, b WHERE a.x = b.y
UNION 语句中明明是会执行两次查询操作,而 OR语句只有一次查询,OR语句反而会慢一点,这是为什么呢?
实际测试分析
对用户表 users 进行查询,表中 user_id 字段建有索引
目标
查找 user_id='IjPEBWuEQZ'
或者 user_id='FwYEz8Bzp' 的记录
采用 OR 语句:
select * from users
where user_id='IjPEBWuEQZ' or user_id='FwYEz8Bzp'
采用 UNION 语句:
select * from users
where user_id='IjPEBWuEQZ'
union
select * from users
where user_id='FwYEz8Bzp'
分别对这两个sql进行 explain 分析
OR 语句的结果
UNION 语句的结果
我们来比较下重要指标,发现主要差别是 type 和 ref 这两项
type 显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range> index > ALL
UNION 语句的 type 值为 ref,OR 语句的 type 值为 range,可以看到这是一个很明显的差距
UNION 语句的 ref 值为 const,OR 语句的 type 值为 null,const 表示是常量值引用,非常快
这两项的差距就说明了 UNION 要优于 OR
从我们的直观感觉上也可以理解,虽然这两个方式都用到了索引,但 UNION 是用一个明确的值到索引中查找,目标非常明确,OR 需要对比两个值,目标相对要模糊一些,所以 OR 在恍惚中落后了