大数据&云计算MySQL性能优化做得好的人,都懂的索引绝技( 五 )


这是建表的时候 InnoDB 就会自动建立好主键 ID 索引树 , 这也是为什么 Mysql 在建表时要求必须指定主键的原因 。 当我们为表里某个字段加索引时 InnoDB 会怎么建立索引树呢?比如我们要给 user_name 这个字段加索引 , 那么 InnoDB 就会建立 user_name 索引 B+树 , 节点里存的是 user_name 这个 KEY , 叶子节点存储的数据的是主键 KEY 。 注意 , 叶子存储的是主键 KEY!拿到主键 KEY 后 , InnoDB 才会去主键索引树里根据刚在 user_name 索引树找到的主键 KEY 查找到对应的数据 。

大数据&云计算MySQL性能优化做得好的人,都懂的索引绝技
本文插图
问题来了 , 为什么 InnoDB 只在主键索引树的叶子节点存储了具体数据 , 但是其他索引树却不存具体数据呢 , 而要多此一举先找到主键 , 再在主键索引树找到对应的数据呢?
其实很简单 , 因为 InnoDB 需要节省存储空间 。 一个表里可能有很多个索引 , InnoDB 都会给每个加了索引的字段生成索引树 , 如果每个字段的索引树都存储了具体数据 , 那么这个表的索引数据文件就变得非常巨大(数据极度冗余了) 。 从节约磁盘空间的角度来说 , 真的没有必要每个字段索引树都存具体数据 , 通过这种看似“多此一举”的步骤 , 在牺牲较少查询的性能下节省了巨大的磁盘空间 , 这是非常有值得的 。
在进行 InnoDB 和 MyISAM 特点对比时谈到 , MyISAM 查询性能更好 , 从上面索引文件数据文件的设计来看也可以看出原因:MyISAM 直接找到物理地址后就可以直接定位到数据记录 , 但是 InnoDB 查询到叶子节点后 , 还需要再查询一次主键索引树 , 才可以定位到具体数据 。 等于 MyISAM 一步就查到了数据 , 但是 InnoDB 要两步 , 那当然 MyISAM 查询性能更高 。
本文首先探讨了哪种数据结构更适合作为 Mysql 底层索引的实现 , 然后再介绍了 Mysql 两种经典数据引擎 MyISAM 和 InnoDB 的底层实现 。 最后再总结一下什么时候需要给你的表里的字段加索引吧:

  • 较频繁的作为查询条件的字段应该创建索引;
  • 唯一性太差的字段不适合单独创建索引 , 即使该字段频繁作为查询条件;
  • 更新非常频繁的字段不适合创建索引 。


推荐阅读