一本彻底搞懂MySQL索引优化EXPLAIN百科全书 (9)

EXPLAIN SELECT * FROM staff WHERE s_no !=1 AND s_no != 2;
EXPLAIN SELECT * FROM staff WHERE s_no NOT IN (1,2);

file

使用IN优化,命中索引:

EXPLAIN SELECT * FROM staff WHERE s_no IN (11,12);

file

但是使用 IN 命中索引有个前提,是查询条件字段数据区分度要高,通常如:状态、类型、性别之类的字段。

** 12、排序对索引的影响**

ORDER BY是经常用的语句,排序也遵循最左前缀列的原则。

查询所有列未命中索引:

EXPLAIN SELECT * FROM staff ORDER BY name,work_age;

file

覆盖索引查询可命中索引:

file

覆盖索引能够利用联合索引查询,但是 ORDER BY 后的条件查询不符合最左前缀原则,执行结果 Extra 中出现了 Using filesort 的提示,一般看到这个就要想办法优化了。

调整排序的两个字段顺序之后,Extra 会提示为 Using index,使用了索引,避免了排序的资源开销:

EXPLAIN SELECT name,work_age FROM staff ORDER BY name,work_age;

file

** 13、局部索引的使用**

局部索引,区别于最左列索引(顺序取索引中靠左的列的查询),它只取某列的一部分作为索引。

INNODB存储引擎下,一般是字符串类型,很长,全部作为索引大大增加存储空间,索引也需要维护,对于长字符串,又想作为索引列,可取的办法就是取前一部分(局部),代表一整列作为索引串。

如何确保这个前缀能代表或大致代表这一列?MySQL中有个概念是 索引选择性,是指索引中不重复的值的数目(也称基数X)与整个表该列记录总数(T)的比值。基数可以通过SHOW INDEX FROM 表名 查看。

比如一个列表 [1,2,2,3,5,6],总数是 6,不重复值数目为 5,选择性为 5/6,因此选择性范围是[X/T, 1],这个值越大,表示列中不重复值越多,越适合作为局部索引,而唯一索引(UNIQUE KEY)的选择性是1。

`SELECT COUNT(DISTINCT(CONCAT(LEFT(remark, N))/COUNT(*) FROM t; 测试出接近 1 的索引选择性,其中N是索引的长度,穷举法去找出N的值,然后再建索引。

创建 局部索引 ,使用 remark 字段举个例子

EXPLAIN SELECT * FROM staff where remark LIKE 'xxx%';

file

对 remark 字段重建局部索引:

ALTER TABLE staff DROP INDEX idx_remark_part, ADD INDEX idx_remark_part(remark(5));

再次执行查询:

EXPLAIN SELECT * FROM staff where remark LIKE 'xxx%';

file

索引优化总结

上面列了大部分场景索引最佳实战,除此之外,不宜建索引的几点小总结:

1)更新非常频繁字段不宜建索引

因为字段更新台频繁,会导致B+树的频繁的变更,重建索引。所以这个过程是十分消耗数据库性能的。

2)区分度不大的字段不宜建索引

比如类似性别这类的字段,区分度不大,建立索引的意义不大。因为不能有效过滤数据,性能和全表扫描相当。另外注意一点,返回数据的比例在 30% 之外的,优化器不会选择使用索引。

3)业务中有唯一特性的字段,建议建成唯一索引

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyxwsz.html