为什么查询速度会变慢
优化查询就是优化其子任务。要么消除一些子任务,要么减少子任务执行的次数,要么让子任务运行的更快。
慢查询基础:优化数据访问
查询性能低下最基本的原因是访问的数据太多
是否向数据库请求了不需要的数据
查询不需要的数据:通常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语句来定义
无法使用查询缓存
不能在使用常量或者标识符的地方使用
只在一个连接里有效
优化排名语句
避免重复查询刚刚更新的语句
统计和更新插入的数量
确定取值的顺序