索引的作用

  • 提高查询效率

  • 消除数据分组/排序

  • 避免”回表”查询

  • 优化聚合查询

  • 用于多表JOIN关联查询

  • 利用唯一性约束,保证数据唯一性

  • InnoDB行锁实现

  • 增加I/O成本

  • 增加磁盘空间

  • 不适合的索引,或索引过多,都不是好事

索引类型

  • BTREE,InnoDB & MyISAM

  • Fractal TREE,TokuDB

  • HASH HEAP NDB InnoDB AHI

  • RTREE

  • FULLTEXT

聚集索引

  • 一种特殊索引,其key值顺序决定了表数据行的 物理(相对)

  • 每张表只能建一个聚集索引,除了TokuDB引擎

  • InnoDB中,聚集索引即表,表即聚集索引

  • MyISAM没有聚集索引的概念

  • 聚集索引优先选择列

    • INT/BIGINT

    • 数据连续(单调顺序)递增/自增

  • 不建议的聚集索引

    • 修改频繁的列

    • 新增数据太过离散

主键索引

  • 主键由表中的一个或多个字段组成

  • 用于唯一地标识表中的某一个记录&外键约束;

  • 主键值不能重复,也不能包含NULL;

  • InnoDB聚集索引选择次序原则

    • 显示声明的主键

    • 第一个NOT NULLABLE的唯一索引

    • ROWID(实例级,6bytes)

  • InnoDB主键特点

    • 索引定义时,不管有无显式包含主键,实际都会存储主键

    • 在5.6.9后,优化器已能自动识别索引末尾的主键值(Index Extensions),在这之前则需要显示加上主键列才可以被识别

    • WHERE c1=? AND PK=?

    • WHERE c1=? ORDER BY PK

辅助索引

  • 非聚集索引,或者二级索引,俗称普通索引

  • 当通过InnoDB辅助索引来查找数据的时候,辅助索引会通过页级的指针来找到主键索引的主键,然后通过该主键索引找到相应的行数据

联合索引

  • 多列组成,所以也叫多列索引

  • 适合WHERE条件中的多列组合

  • 有时候,还可以用于避免回表(覆盖索引)

  • MySQL还不支持多列不同排序规则(MySQL8.0起支持)

  • 联合索引建议

    • WHERE条件中,经常同时出现的列放在联合索引中

    • 把选择性(过滤性/基数)大的列放在联合索引的最左边

部分索引

  • 部分索引的原因

    • char/varchar太长全部做索引的话,效率太差,存在浪费

    • 或者blob/text类型不能整列作为索引列,因此需要使用前缀索引

  • 部分索引选择建议

    • 统计平均值

    • 满足80%-90%覆盖度就够

  • 缺点

    • 无法利用前缀索引完成排序

覆盖索引

  • 通过索引数据结构,即可直接返回数据

InnoDB索引

  • 索引最大长度767bytes

  • 启用innodb_large_prefix,增加到3072bytes,只针对DYNAMIC、COMPRESSED格式管用

  • 对于REDUNDANT、COMPACT格式,最大索引长度还是767bytes

  • MyISAM表索引最大长度是1000bytes

  • 最大默认排序长度1000bytes

索引统计

  • show index from table

  • select * from I_S.STATISTICS

  • mysql.innodb_index_xxxx

  • innodb_stats_auto_recalc

    • 默认启用