Mysql 索引

Posted by YaPi on April 14, 2018

类别

Mysql 中 :

  1. 如果一个主键被定义了,那么这个主键就是作为聚集索引
  2. 如果没有主键被定义,那么该表的第一个唯一非空索引被作为聚集索引
  3. 如果没有主键也没有合适的唯一索引,那么innodb内部会生成一个隐藏的主键作为聚集索引,这个隐藏的主键是一个6个字节的列,改列的值会随着数据的插入自增。

InnoDB引擎会为每张表都加一个聚集索引,而聚集索引指向的的数据又是以物理磁盘顺序来存储的,自增的主键会把数据自动向后插入,避免了插入过程中的聚集索引排序问题。如果对聚集索引进行排序,这会带来磁盘IO性能损耗是非常大的。

Sqlserver 可以自定义非主键的索引

  • 聚集索引
    1. 一个表中只能有一个,聚集索引的顺序与数据真实的物理存储顺序一致。查询速度贼快,聚集索引的叶子节点上是该行的所有数据,数据索引能加快范围查询(聚集索引的顺序和数据存放的逻辑顺序一致)。主键!=聚集索引。
  • 辅助索引(非聚集索引)
    1. 一个表中可以有多个,叶子节点存放的不是一整行数据,而是键值,叶子节点的索引行中还包含了一个’书签’,这个书签就是指向聚簇索引的一个指针,从而在聚簇索引树中找到一整行数据。
  • 联合索引
    1. 一个表中可以有多个,叶子节点存放的不是一整行数据,而是键值,叶子节点的索引行中还包含了一个’书签’,这个书签就是指向聚簇索引的一个指针,从而在聚簇索引树中找到一整行数据
  • 覆盖索引
    1. 指从辅助索引中就能获取到需要的记录,而不需要查找聚簇索引中的记录。使用覆盖索引的一个好处是因为辅助索引不包括一条记录的整行信息,所以数据量较聚集索引要少,可以减少大量io操作
  • 聚集索引与辅助索引的区别
    1. 叶子节点是否存放的为一整行数据
  • 最左前缀规则
    1. 假设联合索引由列(a,b,c)组成,则一下顺序满足最左前缀规则:a、ab、abc;selece、where、order by 、group by都可以匹配最左前缀。其它情况都不满足最左前缀规则就不会用到联合索引。

优化策略

基本原则

  1. 索引需能查找到所有需要的数据
  2. 尽可能索引出的数据和需排序的顺序相同,将索引列作为排序列
  3. 创建的索引需要包含尽可能的查询列
  • 索引必须是独立的列,不能用作表达式或算式 : 如 where a-b > 10
  • 对于某一列数据过长的数据需要做前缀索引
  • 建立多列索引
    1. 5.0 以前的 a or b 会全表查询,除非使用 union
    2. 5.0 后会进行索引合并比如:
      1. a or b
      2. a and b
      3. a or b and c
  • b 树索引中,是从左至右进行排序的,所以需将性能最好的列放在最左边
  • 覆盖索引
    1. 一个索引包含所有需查询的字段,则称为覆盖索引

SQL中不使用索引的情况

  1. 不使用where
  2. %号出现在最左边
  3. 数值类型不等操作、表达式操作或者是、函数操作
  4. 使用or,可改为union all
  5. 需要进行隐式类型转换的
  6. 不满足最左前缀原则