随笔Mysql 索引原理(一)

最近在将自己平时在云笔记的一些东西挪到博客来

  • 索引优化,不得不从了解数据类型开始
  • 索引基础信息
  • 索引的本质
  • Mysql中索引的实现
  • 索引使用策略及优化
  • 索引选择性与前缀索引
  • InnoDB的主键选择与插入优化

索引优化,不得不从了解数据类型开始

  • 建议:越简单的数据类型需要的CPU周期就越少,使用Mysql设定的类型,通常比什么数据都使用varchar数据比较快。
  • 建议:尽量避免NULL,Mysql难以优化引用可空列的查询,会是索引,索引统计和值更加复杂。(因性能优化提升很小,因此除非它引出了问题,否则可不当做首先优化措施)
  • 字符类型,使用varchar和char,区别在可以前者为可变长度,后者为固定长度
    使用varchar时,列(varhcar(50))越短使用的内存则会越小,对排序或者基于内存的临时表开销会更小。
  • lob和Text类型:
  • 日期和时间类型,
  • datatime: 保存时间范围大,精度为秒,与时区无关,使用8字节存储
  • timestamp: 精度为秒,依赖时区,使用4字节存储,
  • 。。。。等等

索引基础信息

  • 数据结构-B树:一种平衡的多路查找树,具有属性:
  • 如果根节点不是叶结点,则至少需要两个子树
  • 每个非根的分支节点,都有k-1个元素和k个子分支节点
  • 所有叶结点都位于同一层次
  • B+数和普通B树的差异:
  • 有N颗子树的节点中包含N个关键字()
  • 所有叶子节点包含所有关键字,及向含这些关键字数据的指针,叶子节点本身以关键字的大小自小到大顺序链接。
  • 所有分支节点可看成索引,节点中仅含有其子树最大或最小的关键字。
  • 索引的本质
  • 索引(Index)是帮助MySQL高效获取数据的数据结构

Mysql中索引的实现

  • InnoDB索引实现
  • 在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。
  • InnoDB的所有辅助索引都引用主键作为data域,而不是地址。
  • 聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
  • 不建议:使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。
  • 建议:非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。
  • MyISAM索引实现
    !待补!

索引使用策略及优化

  • 结构优化(Scheme optimization)
  • 查询优化(Query optimization

索引选择性与前缀索引

  • 不必建索引:
  • 表记录比较少,例如一两千条甚至只有几百条记录的表,没必要建索引,让查询做全表扫描就好了。
  • 索引的选择性较低。所谓索引的选择性(Selectivity),是指不重复的索引值(也叫基数,Cardinality)与表记录数(#T)的比值:Index Selectivity = Cardinality / #
  • 使用前缀索引
  • 概念:前缀索引,是指将用列的前缀代替整个列作为索引key,当前缀长度合适时,可以做到既使得前缀索引的选择性接近全列索引,同时因为索引key变短而减少了索引文件的大小和维护开销。
  • 缺点:不能用于ORDER BY和GROUP BY操作。也不能用于Covering index

InnoDB的主键选择与插入优化

  • 在使用InnoDB存储引擎时,如果没有特别的需要,请永远使用一个与业务无关的自增字段作为主键。
  • (待解决)排序(ORDER BY)相关的索引优化及覆盖索引(Covering index)