MySQL 索引原理解析

Referencehttp://tech.it168.com/a2011/0711/1216/000001216087_all.shtml

  内节点不存储data,只存储key;叶子节点不存储指针。

  同样也是一颗B+Tree,data域保存数据记录的地址。因此,MyISAM中索引检索的算法为首先按照

B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,

读取相应数据记录。

  MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。

1 InnoDB索引实现

  虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。

  第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文

件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的

一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因

此InnoDB表数据文件本身就是主索引。

  第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句

话说,InnoDB的所有辅助索引都引用主键作为data域。 聚集索引这种实现方式使得按主键的搜索十

分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中

检索获得记录。


  了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的

索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引

,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意

,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B

+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段(貌似在replication同步的时候自增有

隐患)作为主键则是一个很好的选择。

2 索引使用策略及优化

  MySQL的优化主要分为结构优化(Scheme optimization)和查询优化(Query optimization)。本章

讨论的高性能索引策略主要属于结构优化范畴。本章的内容完全基于上文的理论基础,实际上一旦理

解了索引背后的机制,那么选择高性能的策略就变成了纯粹的推理,并且可以理解这些策略背后的逻

辑。

(1)最左前缀原理与相关优化

  高效使用索引的首要条件是知道什么样的查询会使用到索引,这个问题和B+Tree中的“最左前缀

原理”有关

  MySQL的查询优化器会自动调整where子句的条件顺序以使用适合的索引


情况一:全列匹配。
情况二:最左前缀匹配。
情况三:查询条件用到了索引中列的精确匹配,但是中间某个条件未提供。
    值少的话,用in来填坑
情况四:查询条件没有指定索引第一列。
    no use index
情况五:匹配某列的前缀字符串。
    此时可以用到索引,但是如果通配符不是只出现在末尾,则无法使用索引。
情况六:范围查询。
  范围列可以用到索引(必须是最左前缀),但是范围列后面的列无法用到索引。同时,索引最多用

于一个范围列,因此如果查询条件中有两个范围列则无法全用到索引。

情况七:查询条件中含有函数或表达式。

  很不幸,如果查询条件中含有函数或表达式,则MySQL不会为这列使用索引(虽然某些在数学意义

上可以使用)。


3 索引选择性与前缀索引

所谓索引的选择性(Selectivity),是指不重复的索引值(也叫基数,Cardinality)与表记录数(#T)的

比值:
Index Selectivity = Cardinality / #T
SELECT count(DISTINCT(title))/count(*) AS Selectivity FROM employees.titles;
+-------------+
| Selectivity |
+-------------+
| 0.0000 |
+-------------+
title的选择性不足0.0001(精确值为0.00001579),所以实在没有什么必要为其单独建索引。

前缀索引
ALTER TABLE employees.employees
  ADD INDEX `first_name_last_name4` (first_name, last_name(4));

4 InnoDB的主键选择与插入优化

  在使用InnoDB存储引擎时,如果没有特别的需要,请永远使用一个与业务无关的自增字段作为主键。
  经常看到有帖子或博客讨论主键选择问题,有人建议使用业务无关的自增主键,有人觉得没有必要,完全可以使用如学号或身份证号这种唯一字段作为主键。不论支持哪种论点,大多数论据都是业务层面的。如果从数据库索引优化角度看,使用InnoDB引擎而不使用自增主键绝对是一个糟糕的主意。
......
  因此,只要可以,请尽量在InnoDB上采用自增字段做主键。


你可能感兴趣的:(MySQL 索引原理解析)