MySQL索引介绍

索引是什么

索引(index)是帮助MySQL高效获取数据的数据结构
如果没有特别指明,都是指的是B树索引(多路搜索树,并不一定是二叉树)结构组织的索引

建立索引的优势和劣势

优势

提高数据检索的效率,降低数据库IO成本,通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。

劣势

实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也要占用空间,因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。

索引的分类

  • 单值索引:即一个索引只包含单个列,一张表可以有多个单列索引(单张表最好不要大于5个索引)
  • 唯一索引:索引列的值唯一,但允许为空
  • 复合索引:一个索引包含多个列

索引的基本语法

  • 创建索引:create [unique] index indexName on tableName(columnName(length))
  • 删除索引:drop index [indexName] on tableName
  • 修改索引: alert table add [unique] index indexName on (columnName(length))
  • 查询索引:show index from tableName

适合创建索引的情况

  • 主键自动创建唯一索引
  • 频繁作为查询条件的字段应该建立索引
  • 查询中与其他表关联的字段,外键关联建立索引
  • 单键和组合索引的选择问题,who?(在高并发的情况下更好建立组合索引)
  • 查询中排序的字段,排序字段若通过索引去访问讲大大提高查询效率,排序效率
  • 查询中统计或者分组字段

不适合建立索引的情况

  • 频繁更新的字段不适合建立索引(因为每次更新不光维护数据,还需要维护索引)
  • where条件里用不到的字段不创建索引
  • 表的记录少
  • 数据重复且分布均匀的表字段,因此应该只为经常查询和最经常排序的数据列建立索引
  • 注意,如果某个数据列包含大量重复内容,那么为他建立索引将没有什么意义

阿里巴巴开发手册索引规范

  • 【强制】业务中具有唯一特性的字段,即使是多个字段组合,也必须建立唯一索引
    说明:不要以为唯一索引影响了insert速度,这个速度损耗是可以忽略的,但提高查询速度是明显的;另外,即使在应用层做了非常完善的校验措施,只要没有唯一索引,根据墨菲定律,必然会又脏数据的出现。
  • 【强制】超过三个表禁止join。需要join的字段数据类型必须一样;多表关联查询时,保证被关联的字段需要建立索引。
    说明:即使双表join也要注意表索引、SQL性能
  • 【强制】在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。
    说明:索引长度与区分度是一对矛盾体,一般字符串类型数据,长度为20的索引,区分度高达90%以上,可以使用count(distinct left(列名,索引长度))/count(*)的区分度来确定
  • 【强制】页面搜索严禁左模糊查询或者全模糊查询,如果需要请走搜索引擎查a_b_c询
    说明:索引文件是具有B-Tree的最左前缀匹配特性,如果左边值未确定,那么无法使用索引
  • 【推荐】如果有order by的场景,请注意利用索引的有序性order by最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情况,影响查询效率
    正例:where a=? and b=? and c=? 索引:a_b_c
    反例:索引中有范围查找,那么索引有序性无法利用,如:where a>10 order by b=?;索引:a_b无法排序
  • 【推荐】利用覆盖索引来进行查找操作,避免回表。
    说明:如果一本书需要知道第11章是什么标题,会翻开第11章的那一页吗?目录浏览一下就好,这个目录就是起到覆盖索引的作用
    正例:能够建立索引的种类:主键索引,唯一索引,普通索引,而覆盖索引是一种查询的一种效果,用explain的结果,extra列会出现:using index
  • 【推荐】利用延迟关联或者子查询优化超多分页场景
    说明:MySQL并不是跳过offset行,而是取offset+N行,然后返回放弃前offset,返回N行,那么当offset特别大的时候,效率就会特别低下,要么控制返回的总页数,要么对超过特定阈值的页数进行改写。
    正例:先快速定位需要获取的 id 段,然后再关联:
    SELECT a.* FROM 表 1 a, (select id from 表 1 where 条件 LIMIT 100000,20 ) b where a.id=b.id
  • 【推荐】:SQL性能优化的目标:至少要达到rang级别,要求是ref级别,如果可以是consts最好。
    说明consts单表中最多只有一个匹配行(主键或者唯一索引),在优化阶段即可读取到数据。
    ref指的是使用普通的索引(normal index)
    rang对索引进行范围检索
    反例explain表的结果,type=index,索引物理文件全扫描,速度非常慢,这个index级别比较range还低,与全表扫描是小巫见大巫
  • 【推荐】建立组合索引时,区分度最高的在最左边
    正例:如果where a=? and b=?, a列的几乎接近于唯一值,那么只需要单建idx_a索引即可
    说明:存在非等号和等号混合判断条件时,在建索引时,请把等号条件的列前置。如:where a>? and b=? 那么即使a的区分度更高,也要把b放在索引的前列
  • 【推荐】防止因字段类型不同造成的隐式转换,导致索引失效
  • 【参考】创建索引时避免有如下极端误区
  1. 宁滥勿缺。认为一个查询就需要建一个索引
  2. 宁缺毋滥。认为索引会消耗空间、严重拖慢更新和新增效率
  3. 抵制唯一索引。认为业务的唯一性一律需要在应用层通过“先查后插”方式解决

你可能感兴趣的:(MySQL,索引,数据库,mysql,java)