mysql调优策略

mysql执行流程

在这里插入图片描述
connector:主要负责处理客户端的连接、获取权限、维持、管理连接等
analyzer:主要负责词法分析、语法分析
optimizer:主要负责做优化,如选择合适的索引、判断条件执行的顺序、查表的顺序等等
actuator:主要负责校验权限、执行sql

索引

此处以mysql5.7为例

索引类型

索引总共有四种类型:

  • BTREE
  • HASH
  • FULLTEXT
  • SPATIAL
    在这里插入图片描述

下面分别来介绍一下:

HASH

hash的基本结构是数组+链表,在mysql中也是如此,因此会存在hash冲突的情况,举例说明

select * from tableA where name='kevin'

如果我们在name字段上建立hash索引,那么
在执行上述sql的时候会先通过hash算法计算kevin的下标,然后从链表中选择目标数据

需要注意的事,如果我们的sql是

select * from tableA where name>'kevin'

这是hash索引就没办法了,hash索引不支持范围查询,这种情况会转化为全表扫描

ps.innodb引擎下会自动把hash索引转化为BTRE类型的索引,因此实际上innodb不支持hash索引

FULLTEXT

全文索引只支持char、varchar、text类型的字段,支持innodb引擎
创建语句如下

ALTER TABLE commpany_info ADD FULLTEXT INDEX idx_cname (company_name) WITH PARSER ngram;

使用全文索引

select * from commpany_info WHERE MATCH (company_name)AGAINST ('一路 一带');

建索引时会对字段按分词器进行分词,查询时通过分词查找结果
使用的较少了解即可

SPATIAL

空间索引使用较少,略过

BTREE

b树索引,这是Innodb默认使用B+树的索引结构。
先说下B树的基本结构,如下图
在这里插入图片描述

可以看到,B数一个节点可以存储多个元素,因此高度相对较低,而B+树则更进一步
在这里插入图片描述
可以看到B+树除了一个节点能储存多个元素之外,还会在叶子节点冗余非叶子节点的数据,且叶子节点之间用指针相连,因此B+树在范围查找上效率会更高

优化

  1. 排除缓存干扰
    通过mysql执行流程可以发现,MySQL会先检查缓存,因此不排除缓存的干扰可能无法获取正确的sql执行时间。使用SQL_NO_CACHE排除缓存干扰
select SQL_NO_CACHE * from tableA
  1. 加索引
  2. explain 查看执行计划
EXPLAIN select * from commpany_info WHERE company_name='Renuka Feeds Private Limited';

在这里插入图片描述

type如果是ALL说明是全表扫描需要优化,一般正常使用索引会是ref
possible_keys表示mysql选择的索引
rows表示扫描的行数,数字越大,效率越低
Extra后文再说
4. 覆盖索引
在普通索引中索引上只保存了当前字段值以及主键值,因此如果我们执行如操作那在查询过程中会进行回表,从而降低查询速度

select * from commpany_info WHERE company_name='Renuka Feeds Private Limited';

为了避免回表,就有了覆盖索引的概念,我们可以把我们需要的字段都放在索引中(即联合索引),或者仅仅查询索引中包含的字段,如

select company_name from commpany_info WHERE company_name='Renuka Feeds Private Limited';

如何判断是否回表?我们可以执行explain,如果extra中出现"Using Index"则说明没有回表
在这里插入图片描述

  1. 联合索引
  2. 最左匹配
    比如我们在A、B、C三个字段上建立联合索引,实际上我们建立了A、AB、ABC三个索引,因此我们使用A字段进行查找时会使用到索引,而是用B、C查找时不会使用索引
  3. 索引下推
    这是Mysql帮咱们实现的,主要用于在非聚簇索引时的多条件查询减少回表
    举例一张表中有索引index_name(colA,colB),执行sql select * from tableA where colA=1 and colB like ‘aa%’ 时会现在索引中过滤数据,然后再回表查询
  4. 普通索引/唯一索引
    首先需要引入change buffer的概念,msyql执行更新操作时如果数据页在内存中则直接更新,否则将缓存操作更新在change buffer中;下次查询如果取到的需要更新的数据所在的数据页时,则把change buffer中的更新语句执行,写入数据页中。因此在写多读少的任务中适合使用change buffer
    普通索引和唯一索引的主要区别在更新过程中,假设需要更新的数据页不在内存中,此时唯一索引由于要保证唯一性因此必须把数据页读到内存中,因此唯一索引不能使用change buffer,而普通索引可以。
    结论:
    对于写多读少的业务,数据写完后被立即访问的概率较小,在保证业务正常的前提下,推荐使用普通索引;其他情况推荐唯一索引
  5. 函数操作导致索引失效
  6. 隐式转换导致索引失效

猜你喜欢

转载自blog.csdn.net/KevinDai007/article/details/107232546