假设订单业务表结构为:
order(oid, date, uid, status, money, me, …)
其中:
oid,订单 ID,主键
date,下单日期,有普通索引,管理后台经常按照 date 查询
uid,用户 ID,有普通索引,用户查询自己订单
status,订单状态,有普通索引,管理后台经常按照 status 查询
money/me,订单金额/时间,被查询字段,无索引
…
假设订单有三种状态:0 已下单,1 已支付,2 已完成
业务需求,查询未完成的订单,哪个 SQL 更快呢?
select * from order where status!=2
select * from order where status=0 or status=1
select * from order where status IN (0,1)
select * from order where status=0
union all
select * from order where status=1
结论:方案 1 最慢,方案 2,3,4 都能命中索引
但是...
一:union all 肯定是能够命中索引的
select * from order where status=0
union all
select * from order where status=1
说明:
直接告诉 MySQL 怎么做,MySQL 耗费的 CPU 最少
程序员并不经常这么写 SQL(union all)
二:简单的 in 能够命中索引
select * from order where status in (0,1)
说明:
让 MySQL 思考,查询优化耗费的 cpu 比 union all 多,但可以忽略不计
程序员最常这么写 SQL(in),这个例子,最建议这么写
三:对于 or,新版的 MySQL 能够命中索引
select * from order where status=0 or status=1
说明:
让 MySQL 思考,查询优化耗费的 cpu 比 in 多,别把负担交给 MySQL
不建议程序员频繁用 or,不是所有的 or 都命中索引
对于老版本的 MySQL,建议查询分析下