这篇文章来自于对《高性能MySQL》的总结
索引(在mysql中叫做“key”)是存储引擎用于快速找到记录的一种数据结构。
索引基础
就像看书一样,我们想要找我们想看的内容都会翻到书的目录,找到对应的章节。这里的目录就是现实生活中的索引。
在mysql中,在存储引擎用类似的方式使用索引,其先在索引中找到对应值,然后根据匹配的索引记录找到对应的数据行。
索引的类型
Mysql索引的类型有B-Tree索引,哈希索引,空间数据索引(R-Tree),全文索引。
Btree索引
当人们谈论索引的时候,如果没有特别指明类型,多半说的就是B-Tree数据结构来存储数据。大多数Mysql引擎都支持这种索引.Archive引擎是一个例外:5.1之前Archive不支持任何索引,直到5.1才开始支持单个自增列(AUTO_INCREMENT)的索引。
我们使用的术语“B-Tree”,是因为在MySQL在Create Table和其他语句中也使用该关键字。不过底层的存储引擎也可能使用不同的存储结构,例如NDB集群存储引擎内部实际上使用了T-Tree结构存储这种引擎,即使其名字是BTREE;Innodb则使用B+Tree,各种数据结构和算法的变种不在本讨论范围之内。
![B-Tree结构][1]
建立在B-Tree树上的索引(技术上是B+Tree)
B-Tree索引能够加快访问数据的速度,因为存储引擎不再需要进行全表扫描来获取需要的数据,取而代之的是从索引的根节点(图示并未画出)开始进行搜索。根节点槽中存放了指向子节点的指针,存储引擎根据这些指向下层查找。通过比较节点页的值和要查找的值可以找到合适的指针进入下层子节点,这些指针实际上定义了子节点页中值的上限和下限。最终存储引擎要么是找到对应的值,要么该记录不存在。
叶子节点页比较特别,它们的指针指向的是被索引的数据,而不是其他的节点页。
[1]: http://wx2.sinaimg.cn/mw690/7503dc51gy1fcoo7uy3rnj20rh0c7ab2.jpg
索引有效查询方式
全值匹配
全值匹配指的是和索引中的所有列进行匹配,例如前面提到的索引可用于查找姓名为Cuba Allen,出生于1960-01-01的人。
匹配最左前缀
前面提到的索引可用于查找所有姓为Allen的人,即只使用索引的第一列。
匹配范围值
例如前面提到的索引可以用于查找姓在Allen和Barrymore之间的人。这里只使用了索引的第一列。
精确匹配某一列并范围匹配另外一列
前面提到的索引也可用于查找所有姓为Allen,并且名字是字母K开头(比如Kim,Karl等)的人。即第一列last_name全匹配,第二列first_name范围匹配。
只访问索引的查询
B-Tree通常可以支持“只访问索引的查询”,即查询只需要访问索引,而无需访问数据行。这种方式叫做“覆盖索引”。
索引的限制
- 如果不是按照索引的最左列开始查询,则无法使用索引。
- 不能跳过索引中的列。
- 如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找。
总结:索引列的顺序是很重要的,这些限制都和索引列的顺序有关。在优化性能的时候,可能需要使用相同的列但顺序不同的索引来满足不同类型的查询需求。