索引详解与优化

2019-01-11  本文已影响0人  yellow_han

1、索引类型

MySQL中索引的存储类型有两种:BTREE和HASH。
MyISAM和InnoDB存储引擎只支持BTREE索引,MEMORY/HEAP存储引擎可以支持HASH和BTREE索引。

2、索引优缺点

优点
缺点

3、索引分类

  1. 主键索引
    • primary key() 要求关键字不能重复,也不能为null,同时增加主键约束 主键索引定义时,不能命名
  2. 唯一索引
    • unique index() 要求关键字不能重复,同时增加唯一约束
  3. 普通索引
    • 单列索引: 即一个索引只包含单个列,一个表可以有多个单列索引
    • 组合索引: 指在表的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用
  4. 全文索引
    • 类型为FULLTEXT,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建,MySQL中只有MyISAM存储引擎支持全文索引

4、索引设计原则

  1. 索引并非越多越好,一个表中如有大量的索引,不仅占用磁盘空间,而且会影响INSERT、DELETE、UPDATE等语句的性能,因为当表中的数据更改的同时,索引也会进行调整和更新
  2. 避免对经常更新的表设计过多的索引,并且索引中的列尽可能要少,而对经常用于查询的字段应该创建索引,但要避免添加不必要的字段
  3. 数据量小的表最好不要使用索引,由于数据较少,查询花费的时间可能比遍历索引时间还要短,索引可能不会产生优化效果
  4. 在条件表达式中经常用到的不同值较多的列上建立索引,在不同值较少的列上不要建立索引,比如性别字段只有男和女,就没必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度
  5. 当唯一性是某种数据本身的特征时,指定唯一索引。使用唯一索引需能确保定义的列的数据完整性,以提高查询速度
  6. 在频繁排序或分组(即group by或order by操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引
  7. 如果需要索引很长的字符串,此时需要考虑前缀索引,在保证其选择性为1。计算该列完整列的选择性,使得前缀选择性接近于完整列的选择性
  8. 尽量使用多列索引
  9. 选择合适的索引列顺序

5、索引使用原则

  1. 列独立
    • 保证索引包含的字段独立在查询语句中,不能是在表达式中
  2. 左前缀
    • like:匹配模式左边不能以通配符开始,才能使用索引 注意:前缀索引在排序 order by 和分组 group by 操作的时候无法使用。
  3. 复合索引由左到右生效
    • 建立联合索引,要同时考虑列查询的频率和列的区分度。
  4. 不要滥用索引,多余的索引会降低读写性能
    • 即使满足了上述原则,mysql还是可能会弃用索引,因为有些查询即使使用索引,也会出现大量的随机io,相对于从数据记录中的顺序io开销更大。

6、Btree和Hash的区别以及使用场景

7、性能分析

Explain:看一条 SQL 语句的性能,可以使用 explain 关键字查看语句性能

8、存在索引但不能使用索引的典型场景

1. 以%开头的 like 查询不能利用 B-Tree 索引,执行计划中 key 的值为 null 表示没有使用索引
2. 数据类型出现隐式转换的时候也不会使用索引
3. 复合索引的情况下,假如查询条件不包含索引列最左边部分,即不满足最左原则 leftmost,是不会使用复合索引的。
4. 如果 MySQL 估计使用索引比全表扫描更慢,则不使用索引。
5. 用 or 分割开的条件,如果 or 前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。

9、聚集索引与非聚集索引

1. 聚集索引

InnoDB的数据文件本身就是索引文件,B+Tree的叶子节点上的data就是数据本身,key为主键,非叶子节点存放<key,address>,address就是下一层的地址。


image.png
2. 非聚集索引

非聚簇索引,叶子节点上的data是主键(即聚簇索引的主键,所以聚簇索引的key,不能过长)。


image.png

9、索引实战分析

1. 主键索引
explain SELECT * FROM store_goods WHERE id = '10002'
image.png
2、唯一索引
explain SELECT * FROM store_goods WHERE goods_sn = 'X14481662'
image.png
3、普通索引(单列)
EXPLAIN SELECT * FROM store_orders WHERE shop_id = '37';
image.png
4、普通索引(组合)
EXPLAIN SELECT * FROM d_part_record WHERE draw_id = '1082839908363476994' and mid = '2'
image.png
索引使用

参考链接

https://juejin.im/entry/5a448726f265da43062b10f1
https://juejin.im/entry/59a8fa9f5188251d445fb9fb
https://juejin.im/post/5a6873fbf265da3e393a97fa
https://juejin.im/post/5b6fd2b85188256128593eca
https://juejin.im/post/5ab34d21f265da23766b30ed

上一篇 下一篇

猜你喜欢

热点阅读