MySQL必知必会——查询性能优化

52 阅读4分钟

为什么查询速度会变慢

优化查询就是优化其子任务。要么消除一些子任务,要么减少子任务执行的次数,要么让子任务运行的更快。

慢查询基础:优化数据访问

查询性能低下最基本的原因是访问的数据太多

是否向数据库请求了不需要的数据

查询不需要的数据:通常mysql会查询出全部的数据集,然后客户端的应用程序会接受全部的数据集,然后抛弃其中的大部分

取出全部列没法进行索引覆盖扫描

查询相同的数据可以将其缓存起来。

mysql是否在扫描额外的记录

有三个指标:响应时间、扫描的行数、返回的行数。这仨指标会记录在慢日志里。响应时间是排队时间+服务时间

用快速上限估计法来估算查询的响应时间

理想状态下扫描的行数和返回的行数是一样的

重构查询的方式

一个复杂查询还是多个简单查询

切分查询

把一个大的delete语句换成几个小的,可以减少资源的利用。

分解关联查询

对表进行单表查询然后把结果关联

好处如下:

1、缓存效率更高

2、单个查询减少锁的竞争

3、在应用层关联,容易对数据表进行拆分

4、减少冗余

5、实现哈希关联

6、查询本身效率提升

查询执行基础

mysql客户端/服务器通信协议

客户端和服务器之间的协议是半双工的

查询状态:sleep、query、locked、analyzing and statistics、copying to tmp table、sorting result、sending data

查询缓存

查询优化处理

先解析查询语句,形成解析树,然后由优化器将其转换为执行计划

优化策略分为静态优化和动态优化

重新定义关联顺序

避免排序和对大量数据进行排序

mysql有两种排序算法:1、两次传输排序:读取行指针和需要排序的字段,排序完后根据行指针读取所需的数据行。2、单词传输排序:读取查询所需全部列,然后排序,然后返回结果

查询执行引擎

执行计划是一个数据结构不是字节码

返回结果给客户端

返回是一个增量逐步返回的过程。第一是节省内存,第二是让客户端第一时间就能收到结果。

mysql查询优化器的局限性

关联子查询

带in的子查询改成inner join或者exists

union限制

索引合并优化

等值传递

并行执行

不能并行

哈希关联

mysql不支持哈希关联

松散索引扫描

mysql不支持

最大值最小值优化

可以使用limit

在同一个表上查询或更新

先inner join一个临时表,再更新

查询优化器的提示

用提示来控制执行计划

high_priority,low_priority:只对表锁的存储引擎有用

delayed:将语句立刻返回客户端,插入的行数据放回缓冲区,表空闲的时候批量把数据插入

straight_join:1、让表按出现的顺序关联 2、让前后两个表关联顺序固定

优化特定类型的查询

优化count查询

myisam没有where条件才更快

使用近似值,explain的行数

或者增加汇总表和覆盖索引。

优化关联查询

on和using子句的列上有索引,一般在关联的第二个表上建立索引。

确保order by和group by表达式只涉及到第一个表里的列

优化子查询

用关联查询代替

优化group by和distinct

优化limit分页

延迟关联

优化union查询

静态查询分析

使用用户自定义变量

用set和select语句来定义

无法使用查询缓存

不能在使用常量或者标识符的地方使用

只在一个连接里有效

优化排名语句

避免重复查询刚刚更新的语句

统计和更新插入的数量

确定取值的顺序