MySQL-04丨影响索引查询效率的场景

Posted by jiefang on October 28, 2019

响索引查询效率的场景

函数操作

对条件字段做函数操作不走索引

不走索引原因

索引树存储的是列的实际值和主键值,如果拿’2019-05-21’去匹配,将无法定位到索引树中的值,因此放弃走索引,走全表扫描 image

优化技巧

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中避免不了计算的情况,必须把计算放在等号后边。

image