本文缘起自《一分钟了解索引技巧》的作业题。
假设订单业务表结构为:
订单(oid、日期、uid、地位、金钱、时间、…)
其中:
-
<李> oid,订单ID、主键李>
<李>日期、下单日期,有普通索引,管理后台经常按照日期查询李>
<李> uid,用户ID,有普通索引,用户查询自己订单李>
<李>状态,订单状态,有普通索引,管理后台经常按照状态查询李>
<李>金钱/时间,订单金额/时间,被查询字段,无索引李>
<李>…李>
假设订单有三种状态:0已下的单,1已支付,2已完成
业务需求,查询未完成的订单,哪个SQL更快呢?
-
<李> select *从有序状态!=2 李>
<李> select *从有序状态=0或状态=1 李>
<李> select *从有序状态在(0,1)李>
<李> select *从订单状态=0
union all
select *从订单状态=1 李>
结论:方案1最慢,方案2、3、4都能命中索引
但是……
<强>一:union all肯定是能够命中索引的强>
select *从订单状态=0 union all select *从订单状态=1
说明:
直接告诉MySQL怎么做,MySQL耗费的CPU最少
程序员并不经常这么写SQL (union all)
<强>二:简单的,能够命中索引强>
select *从有序状态在(0,1)
说明:
让MySQL思考,查询优化耗费的cpu比联盟都多,但可以忽略不计
程序员最常这么写SQL(在),这个例子,最建议这么写
<强>三:对于或者新版的MySQL能够命中索引强>
select *从有序状态=0或状态=1
说明:
让MySQL思考,查询优化耗费的多cpu比,别把负担交给MySQL
不建议程序员频繁用,或者不是所有的或都命中索引
对于老版本的MySQL,建议查询分析下
<强>四,对于!=⒏合虿檠隙ú荒苊兴饕?/强>
select *从有序状态!=2
说明:
全表扫描,效率最低,所有方案中最慢
禁止使用负向查询
<强>五,其他方案强>
select *从有序状态& lt;2
这个具体的例子中,确实快,但是:
这个例子只举了3个状态,实际业务不止这3个状态,并且状态的“值”正好满足偏序关系,万一是查其他状态呢,SQL不宜依赖于枚举的值,方案不通用
这个SQL可读性差,可理解性差,可维护性差,强烈不推荐
<强>六,作业强>
这样的查询能够命中索引么?
从订单在uid(选择* 选择uid从订单状态=0 ) select *从订单状态(0,1)顺序按日期desc select *从有序状态=0或日期& lt;=CURDATE ()
注:此为示例,别较真SQL对应业务的合理性。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。