什么是索引

索引(Index) 是帮助 MySQL 等数据库高效获取数据的数据结构。我们可以简单理解为:快速查找排好序的一种数据结构。MySQL 索引主要有两种结构:B+Tree索引和 Hash 索引。我们平常所说的索引,如果没有特别指明,一般都是指 B树结构组织的索引 (B+Tree索引)。

常见的索引

约束:

  1. 主键约束【主键索引】
  2. 唯一约束【唯一索引】
  3. 外键约束【外键索引】

索引:

  1. 聚集索引
  2. 联合索引
  3. 覆盖索引
  4. 部分索引【前缀索引】

索引的优缺点

优点:

  1. 提高数据检索效率
  2. 提高表之间的 JOIN 效率
  3. 利用唯一性索引,保证数据的唯一性
  4. 提高排序和分组效率

缺点:

  1. 消耗更多的物理存储
  2. 数据变更时,索引也需要更新,降低了插入、更新效率

索引的使用建议

  1. 经常检索的列
  2. 经常用于表连接的列
  3. 经常排序/分组的列

以下情况不建议使用索引

  1. 基数很低的列
  2. 更新频繁检索不频繁的列
  3. BLOB/TEXT 等大字段列

建立索引的原则

1、最左前缀匹配原则。这是非常重要的原则,MySQL会一直向右匹配直到遇到范围查询(>,<,BETWEEN,LIKE)就停止匹配,比如: a = 1 AND b = 2 AND c > 3 AND d = 4,如果建立 (a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引,则都可以用到,a,b,d的顺序可以任意调整。

2、等于(=)和in 可以乱序。比如,a = 1 AND b = 2 AND c = 3 建立(a,b,c)索引可以任意顺序,MySQL的查询优化器会帮你优化成索引可以识别的模式。

3、尽量选择区分度高的列作为索引,区分度的公式是 COUNT(DISTINCT col) / COUNT(*)。表示字段不重复的比率,比率越大我们扫描的记录数就越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度是0。可能有人会问,这个比率有什么经验么?使用场景不同,这个值也很难确定,一般需要JOIN的字段我们要求在0.1以上,即平均1条扫描10条记录。

4、索引列不能参与计算,尽量保持列“干净”。比如,FROM_UNIXTIME(create_time) = ‘2016-06-06’ 就不能使用索引,原因很简单,B+树中存储的都是数据表中的字段值,但是进行检索时,需要把所有元素都应用函数才能比较,显然这样的代价太大。所以语句要写成 : create_time = UNIX_TIMESTAMP(‘2016-06-06’)。

5、尽可能的扩展索引,不要新建立索引。比如表中已经有了a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

6、单个多列组合索引和多个单列索引的检索查询效果不同,因为在执行SQL时,MySQL只能使用一个索引,会从多个单列索引中选择一个限制最为严格的索引。