本文用于记录苦啃《高性能MySQL(第3版)》后,个人认为有价值的笔记,核心内容均围绕标题展开。既做一个学习的记录,同时也做一个沟通交流,欢迎各位大佬互动~
索引基础
索引(MySQL中叫”键”)是存储引擎用于快速找到记录的一种数据结构。
索引类型
B-Tree索引(未指明时默认的索引类型,使用B-Tree数据结构来存储数据)
基本介绍:
不同存储引擎用不同方式使用B-Tree索引:
MyISAM使用前缀压缩技术使得索引更小,索引通过数据的物理位置引用被索引的行;
InnoDB按照原格式进行存储,索引根据主键引用被索引的行。
结构:
B-Tree以为着所有的值都是按顺序存储的,并且每个叶子页倒根的距离相同。
B-Tree索引能加速访问数据的速度,是因为存储引擎不再需要进行全表扫描来获取需要的数据。而是从索引的根节点开始搜索。
非叶子节点(包括根节点)存储了子节点的指针,通过比较节点页的值和要查找的值可以找到合适的指针进入下层子节点。最终存储引擎要么找到对应的值,要么该记录不存在。
叶子节点他们的指针指向的是被索引的数据。
索引列是顺序组织存储的,因此适合查找范围数据。
适用范围:
全键值、键值范围或键前缀查找。
对以下类型查询有效:
全值匹配、匹配最左前缀(只使用索引的第一列)、匹配列前缀、匹配范围值、精确匹配某一列并范围匹配另外一列、只访问索引的查询。
限制:
- 如果不是按照索引的最左列开始查找,则无法使用索引;
- 不能跳过索引中的列;
- 如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找。
哈希索引
基于哈希表实现,只有精确匹配索引所有列的查询才有效。
对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码,哈希索引将所有哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。
如果多个列的哈希指相同,索引会以链表的方式存放多个指针到同一个哈希条目中。
哈希索引的结构十分紧凑,所以哈希索引查找的速度非常快。
限制:
- 哈希索引指包含哈希值和行指针,不存储字段值。不能通过索引中的值来避免读取行;
- 哈希索引数据不是按照索引值顺序存储的,所以无法用于排序;
- 不支持索引列匹配查找。数据量(A,B)建立哈希索引,只查A则无法使用该索引;
- 只支持等职比较查询,不支持任何范围查询。=、IN()、<=>;
- 当出现哈希冲突时,存储引擎必须遍历链表中所有的行指针;
InnoDB引擎有个特殊功能“自适应哈希索引”。当某些索引值被用的很频繁时,会在内存基于B-Tress索引之上再创建一个哈希索引。
索引的优点
- 索引大大减少了服务器需要扫描的数据量;
- 索引可以帮助服务器避免排序和临时表;
- 索引可以将随机I/O变为顺序I/O
三星系统:
一星:索引将相关的记录放到一起;
二星:索引中的数据顺序和查找中的排列顺序一致;
三星:索引中的列包含了查询中需要的全部列。