博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySql索引优化
阅读量:5010 次
发布时间:2019-06-12

本文共 3374 字,大约阅读时间需要 11 分钟。

在开发中我们经常免不了在业务量大的时候,需要针对数据库的庞大数据量进行优化,以满足响应的效率,今天我们来谈一谈索引的优化。

一、索引的数据结构

mysql主要使用 B-tree 平衡树,索引分为聚簇索引与非聚簇索引,其中:
  • 聚簇索引:索引的叶节点指向数据 
  • 非聚簇索引:索引的叶节点指向数据的引用

常用的引擎myisam使用非聚簇索引,innodb使用聚簇索引

对于innodb引擎:

  1. 主键索引既存储索引值,又在叶中存储行数据
  2. 如果没有主键,则会使用 unique key 做主键
  3. 如果没有unique,则mysql会生成一个rowid做主键 

其优点在于查询数据少时,无须回行,而缺点则是不规则插入数据,频繁的页分裂

 

二、索引类型

1. 主键索引

primary key() 要求关键字不能重复,也不能为null,同时增加主键约束 

主键索引定义时,不能命名

2. 唯一索引

unique index() 要求关键字不能重复,同时增加唯一约束

3. 普通索引

index() 对关键字没有要求

4. 全文索引

fulltext key() 关键字的来源不是所有字段的数据,而是字段中提取的特别关键字(可以是某个字段或多个字段,多个字段称为复合索引

1 建表: 2 creat table student( 3     stu_id int unsigned not null auto_increment, 4     name varchar(32) not null default '', 5     phone char(11) not null default '', 6     stu_code varchar(32) not null default '', 7     stu_desc text, 8     primary key ('stu_id'),     //主键索引 9     unique index 'stu_code' ('stu_code'), //唯一索引10     index 'name_phone' ('name','phone'),  //普通索引,复合索引11     fulltext index 'stu_desc' ('stu_desc'), //全文索引12 ) engine=myisam charset=utf8;13 14 更新:15 alert table student16     add primary key ('stu_id'),     //主键索引17     add unique index 'stu_code' ('stu_code'), //唯一索引18     add index 'name_phone' ('name','phone'),  //普通索引,复合索引19     add fulltext index 'stu_desc' ('stu_desc'); //全文索引20 21 删除:22 alert table sutdent23     drop primary key,24     drop index 'stu_code',25     drop index 'name_phone',26     drop index 'stu_desc';

 

三、索引使用原则

1. 列独立

保证索引包含的字段独立在查询语句中,不能是在表达式中

2. 左前缀

like:匹配模式左边不能以通配符开始,才能使用索引 

注意:前缀索引在排序 order by 和分组 group by 操作的时候无法使用。

3. 复合索引由左到右生效

建立联合索引,要同时考虑列查询的频率和列的区分度。

例如:index(a,b,c)

注:or的两边都有存在可用的索引,该语句才能用索引。

4. 不要滥用索引,多余的索引会降低读写性能

即使满足了上述原则,mysql还是可能会弃用索引,因为有些查询即使使用索引,也会出现大量的随机io,相对于从数据记录中的顺序io开销更大。

 

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

有些时候虽然有索引,但是并不被优化器选择使用,下面举例几个不能使用索引的场景。

1.以%开头的 like 查询不能利用 B-Tree 索引,执行计划中 key 的值为 null 表示没有使用索引, 因为 B-Tree 索引的结构,所以以%开头的插叙很自然就没法利用索引了。一般推荐使用全文索引(Fulltext)来解决类似的全文检索的问题。或者考虑利用 innodb 的表都是聚簇表的特点,采取一种轻量级别的解决方式:一般情况下,索引都会比表小,扫描索引要比扫描表更快,而Innodb 表上二级索引 idx_last_name 实际上存储字段 last_name 还有主键,那么理想的访问应该是首先扫描二级索引 idx_last_name 获得满足条件的last_name like '%NI%' 的主键列表,之后根据主键回表去检索记录,这样访问避开了全表扫描数据表产生的大量 IO 请求。

2. 复合索引的情况下,假如查询条件不包含索引列最左边部分,即不满足最左原则 leftmost,是不会使用复合索引的。

3. 如果 MySQL 估计使用索引比全表扫描更慢,则不使用索引。

4. 用 or 分割开的条件,如果 or 前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。

五、查看索引使用情况

如果索引正在工作, Handler_read_key 的值将很高,这个值代表了一个行被索引值读的次数,很低的值表名增加索引得到的性能改善不高,因为索引并不经常使用。 

Handler_read_rnd_next 的值高则意味着查询运行低效,并且应该建立索引补救。这个值的含义是在数据文件中读下一行的请求数。如果正在进行大量的表扫描,Handler_read_rnd_next 的值较高,则通常说明表索引不正确或写入的查询没有利用索引,具体如下:

 

六、使用索引的小技巧

1. 字符串字段权衡区分度与长度的技巧

截取不同长度,测试区分度

 

区别度能达到0.1,就可以。

2. 左前缀不易区分的字段索引建立方法

这样的字段,左边有大量重复字符,比如url字段汇总的http://

    1. 倒过来存储并建立索引
    2. 新增伪hash字段 把字符串转化为整型
3. 索引覆盖

概念:如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘,这种查询,速度极快,江湖人称——索引覆盖

4. 延迟关联

在根据条件查询数据时,如果查询条件不能用的索引,可以先查出数据行的id,再根据id去取数据行。 

5. 索引排序 

排序的字段上加入索引,可以提高速度。

6. 重复索引和冗余索引

重复索引:在同一列或者相同顺序的几个列建立了多个索引,成为重复索引,没有任何意义,删掉 

冗余索引:两个或多个索引所覆盖的列有重叠,比如对于列m,n ,加索引index m(m),indexmn(m,n),称为冗余索引。

7. 索引碎片与维护

在数据表长期的更改过程中,索引文件和数据文件都会产生空洞,形成碎片。修复表的过程十分耗费资源,可以用比较长的周期修复表。

8. innodb引擎的索引注意事项

Innodb 表要尽量自己指定主键,如果有几个列都是唯一的,要选择最常作为访问条件的列作为主键,另外,Innodb 表的普通索引都会保存主键的键值,所以主键要尽可能选择较短的数据类型,可以有效的减少索引的磁盘占用,提高索引的缓存效果。

总结:

  针对于数据库的优化是的内容非常的多,有些优化往往不在于技术层面而存在于架构层面,在空间与时间上寻找平衡点,没有最好的优化方案,只有更合适的优化方案

 

 

文章作者介绍:

来自于小豹科技的彭文杰-公司专注于软件基础研发平台,目前公司正在研发一款基于Netty的插件式的API网关-。 希望与对OpenAPI、微服务、API网关、Service Mesh等感兴趣的朋友多交流。 有兴趣的朋友请加QQ群244054462。

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/isote/p/8317352.html

你可能感兴趣的文章
岗顶-一图一世界
查看>>
一步步构造自己的vue2.0+webpack环境
查看>>
分页类
查看>>
Python装饰器的个人小理解
查看>>
为什么百万医疗险越来越多,到底选哪款?
查看>>
如何检测 51单片机IO口的下降沿
查看>>
扫描识别控件Dynamic .NET TWAIN使用教程:如何将事件添加到应用程序中
查看>>
创建和修改主键 (SQL)
查看>>
2018-2019 ICPC, NEERC, Southern Subregional Contest(训练记录)
查看>>
20145233 《信息安全系统设计基础》第7周学习总结
查看>>
linux设备驱动程序第3版学习笔记(例程2--hellop.c)
查看>>
玩转storm
查看>>
第10章 使用Apache服务部署静态网站
查看>>
关于给予webApp框架的开发工具
查看>>
c语言编写的生成泊松分布随机数
查看>>
Maven入门笔记
查看>>
iOS webView的常见属性和方法
查看>>
理解position:relative
查看>>
Codeforces Round #344 (Div. 2) Messager KMP的应用
查看>>
20145308刘昊阳 《Java程序设计》第4周学习总结
查看>>