高性能索引策略——《高性能MySQL》第五章

目录

前言

这是阅读《高性能mysql》第五章的记录。

1. 独立的列

非独立的列是索引列是表达式的一部分或是函数的参数,这会导致索引使用不当,或无法使用已有的索引

错误示例

1
select actor_id from sakila.actor where actor_id + 1 = 5;
1
select ... where to_days(current_date) - to_days(date_col) <= 10;

注意

养成简化where条件的习惯,始终将索引列单独放在比较符号的一侧

2. 前缀索引和索引选择性

索引选择性:不重复的索引值(也称为基数,cardinality)和数据表的记录总值(#T)的比值,范围从(1/#T)到1之间。索引选择性越高,查询效率越高。唯一索引的选择性是1,是最好的索引选择性,性能最好。

前缀索引:一般情况下,某个列的前缀选择性足够高,足以满足查询性能。对于BLOB\TEXT\VARCHAR类型的列,必须用前缀索引——mysql不允许索引在这些列的完整长度

诀窍:足够长——保证较高的选择性,不能太长——节约空间。前缀的“基数”应该接近于完整列的“基数”

例子

3. 多列索引

在多列上建立独立的单列索引大部分情况下不能提高Mysql查询性能。

4. 选择合适的索引列顺序

正确的顺序依赖于使用该索引的查询,并且同时需要考虑如何更好地满足排序和分组的需要。

选择性更高的列放在索引最前列,某些场景有用。但通常不如避免随机IO和排序重要。

将选择性最高的列放在前面通常是很好,这时候索引的作用只是用于优化WHERE条件的查找。然而,性能不只是依赖于所有索引列的选择性(整体基数),也和查询条件的具体值有关,也就是和值的分布有关。可能也需要根据那些运行频率最高的查询来调整索引列的顺序,让这种情况下索引的选择性更高

5. 聚簇索引

并非一种单独的索引类型,而是一种数据存储方式。InnoDB的聚簇索引在同一个结构中保存了B-Tree索引和数据行。

6. 覆盖索引

查询只需要扫描索引而无须回表,带来的好处

  • 索引条目通常远小于数据行大小,所以如果只需要读取索引,那么Mysql就会极大地减少数据访问量。这对缓存的负载非常重要,因为这种情况下响应时间大部分花在数据拷贝上。这对I/O密集型的应用也有帮助。
  • 索引是按照列值顺序存储的,所以对于I/O密集型的范围查询会比随机从磁盘读取每一行数据的I/O要少得多
  • 一些存储引擎如MyISAM在内存中只缓存索引,数据则依赖于操作系统来缓存,因此访问数据需要一次系统调用,可能导致严重的性能问题。
  • 对于InnoDB的聚簇索引,覆盖索引对InnoDB表特别有用。InnoDB的二级索引在叶节点中保存了行的主键值,所以如果二级主键能够覆盖查询,则可以避免对主键索引的二次查询

7. 使用索引扫描来做排序

两种方式生成有序结果:排序操作、按索引顺序扫描(explain的type结果为index,而不是extra列的”Using index”)

扫描索引本身很快,但如果索引不能覆盖所有查询所需的全部列,就不得不每扫描一条索引记录就都回表查询一次对应的行。基本上都是随机I/O,因此按索引顺序读取数据的速度他哦农场要比顺序地全表扫描慢,尤其是在I/O密集型的工作负载时。

所以最后的结果,是同一索引既满足排序,又用于查找行

使用索引排序的一个重要用法是当查询同时有ORDER BY 和 LIMIT 子句

8. 压缩(前缀压缩)索引

MyISAM

9. 冗余和重复索引

重复索引——在相同的列上按照相同的顺序创建的相同类型的索引。

冗余索引——如果创建了索引(A,B),再创建索引(A)就是冗余索引,因为这只是前一个索引的前缀索引,加入是再创建(B,A)就不是。通常发生在为表添加新索引的时候。

MySQL允许在相同列创建多个索引。但需要单独维护重复的索引,并且优化器在优化查询时需要逐个考虑,这会影响性能。

大多数情况都不需要冗余索引,应该尽量扩展已有的索引而不是创建新索引。(除非扩展会让索引变得太大了)

10. 未使用的索引

建议考虑删除

定位未使用索引的工具Percona ServerMariaDB查看每个索引的使用频率。

11. 索引和锁

本文标题:高性能索引策略——《高性能MySQL》第五章

文章作者:松子

发布时间:2018年10月27日 - 00:10

最后更新:2022年03月26日 - 22:03

博文链接:https://songzi.info/post/56a6a98a/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%