explain select * from ecs_ad where ad_id =1 or ad_id = 3;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
| 1 | SIMPLE | ecs_ad | range | PRIMARY | PRIMARY | 2 | NULL | 2 | Using index condition |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
1 row in set
这是union all的
explain select * from ecs_ad where ad_id = 4 union all select * from ecs_ad where ad_id = 3;
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
| 1 | PRIMARY | ecs_ad | const | PRIMARY | PRIMARY | 2 | const | 1 | NULL |
| 2 | UNION | ecs_ad | const | PRIMARY | PRIMARY | 2 | const | 1 | NULL |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
3 rows in set
首先,这两个查询性能差距应该不大。
因为 ad_id 列是主键.
根据 type 列分析:
or 查询,
type:range
type:range
union all 查询:
type:const / const / ALL
union all 查询:type:const / const / ALL
首先可以确认的是,
const
要优于range
.const
要优于range
.const
const
也是因为 ad_id 为主键.但是 union all 做了三次操作,两次主键或者唯一索引查询 type:const,但最后组合到一起时 type:ALL
type:ALL 本身性能比 range 还要差
从 Type 看,or 查询性能应该更好.
Extra 分析
or 查询:
Using index condition
Using index condition
union all 查询:
NULL / NULL / Using temporary
union all 查询:NULL / NULL / Using temporary
Using index condition 为 MySQL 5.6 版本以后新添加的特性,索引条件推送。
首先说一下没有索引条件推送时候的处理流程:
当存在索引条件推送时候的处理流程:
简单来说,没有 ICP 时,存储引擎返回所有满足条件的整行数据,在 service 层进行 where 条件过滤。
有 ICP 时,where 条件下推到存储引擎层,存储引擎直接返回满足条件的数据。
性能自然提高很多。
对于 ICP 的相关介绍,可以查看这里
而 Using temporary 表示隐式临时表,意思是 MySQL 会在产生一个临时表,存放中间数据。因为 union all 是分开处理,最后合并的关系。
从 Extra 看,也应该是 or 查询性能更高。
综合来看:OR 查询的性能应该有优于 UNION ALL .
由于所有查询性能都随着数据量增大而变化,以上分析只是单看题主所贴的 Explain 分析结果。也并不是说 OR 在所有情况下都优于 UNION ALL。
以上为个人意见,如有错误,请指正。
这两个语句,无区别。
一般or连接两个不同字段,无法使用索引的时候,性能会比较差,不如union,可以尝试修改。