响索引查询效率的场景
函数操作
对条件字段做函数操作不走索引
不走索引原因
索引树存储的是列的实际值和主键值,如果拿’2019-05-21’去匹配,将无法定位到索引树中的值,因此放弃走索引,走全表扫描
优化技巧
1
select * from t1 where c>='2019-05-21 00:00:00' and c<='2019-05-21 23:59:59';
求某一天或某一月数据的需求,建议写成范围查询,可让查询走索引,避免对索引字段做函数处理。
隐式转换
什么是隐式转换? 当操作符与不同类型操作对象一起使用时,就会发生类型转换以使操作兼容。
1
mysql> explain select * from t1 where a=1000;
隐式转换实际相当于
1
select * from t1 where cast(a as signed int) =1000;
相当于对索引做函数操作,优化器放弃使用索引
模糊查询
1
explain select * from t1 where a like '%1111%';
无法走索引,建议模糊查询必须包含字段前面的值(必须结合业务,如果直接改SQL,会导致结果不正确)
1
explain select * from t1 where a like '1111%';
范围查询
1
2
3
4
5
6
7
8
mysql> explain select * from t1 where b>=1 and b <=2000;
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | t1 | ALL | idx_b | NULL | NULL | NULL | 15455 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
b字段没有走索引,原因是:优化器会根据检索比例,表大小,I/O块大小等进行评估是否走索引。比如单次查询的数据量过大,优化器将不走索引。 优化技巧
1
explain select * from t1 where b>=1 and b <=1000;
降低查询范围后,能正常使用索引。
实际这种范围查询而导致使用不了索引的场景经常出现,比如按照时间段抽取全量数据,每条SQL抽取一个月的;或者某张业务表历史数据的删除。遇到此类操作时,应该在执行之前对SQL做explain分析,确定能走索引,再进行操作,否则不但可能导致操作缓慢,在做更新或者删除时,甚至会导致表所有记录锁住,十分危险。
计算操作
1
explain select * from t1 where b-1 =1000;
对索引字段做运算将使用不了索引 一般需要对条件字段做计算时,建议通过程序代码实现,而不是通过mysql实现。如果在mysql中避免不了计算的情况,必须把计算放在等号后边。