我们一起聊聊MySQL 索引的底层逻辑( 四 )


我们一起聊聊MySQL 索引的底层逻辑

文章插图
图片
上图是 InnoDB 主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录 。这种索引叫做聚集索引 。因为 InnoDB 的数据文件本身要按主键聚集 , 所以 InnoDB 要求表必须有主键( MyISAM 可以没有),如果没有显式指定,则 MySQL 系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则 MySQL 自动为 InnoDB 表生成一个隐含字段作为主键,这个字段长度为 6 个字节,类型为长整形 。第二个与 MyISAM 索引的不同是 InnoDB 的辅助索引 data 域存储相应记录主键的值而不是地址 。换句话说, InnoDB 的所有辅助索引都引用主键作为 data 域 。例如,下图为定义在 Col3 上的一个辅助索引:
我们一起聊聊MySQL 索引的底层逻辑

文章插图
图片
这里以英文字符的 ASCII 码作为比较准则 。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录 。了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了 InnoDB 的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大 。再例如,用非单调的字段作为主键在 InnoDB 中不是个好主意,因为 InnoDB 数据文件本身是一颗 B+Tree ,非单调的主键会造成在插入新记录时数据文件为了维持 B+Tree 的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择 。
总结本文以 MySQL 数据库为研究对象,讨论与数据库索引相关的一些话题 。特别需要说明的是 ,  MySQL 支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此 MySQL 数据库支持多种索引类型,如 B-Tree 索引,哈希索引,全文索引等等 。为了避免混乱,将只关注于 B-Tree 索引,因为这是平常使用 MySQL 时主要打交道的索引 。
参考文献[1] Baron Scbwartz 等 著,王小东等 译;高性能 MySQL(High Performance MySQL);电子工业出版社 , 2010 [2] Michael Kofler 著,杨晓云等 译;MySQL5权威指南(The Definitive Guide to MySQL5);人民邮电出版社,2006 [3] 姜承尧 著;MySQL 技术内幕-InnoDB 存储引擎;机械工业出版社 , 2011




推荐阅读