-
mysql优化参考(三)-select
- 查询慢的原因
- 网络&IO(集群)
- CPU
- IO - 临时表、文件排序,查询数据量
- 上下文切换
- 生成统计信息(Performance_Schema 、Profile等)
- 锁等待时间 - 并发场景(表锁、行锁 | 读锁、写锁 | 【InnoDB-锁的对象:索引】共享锁、排它锁 | 【MyIsAM】共享锁、独占锁)
- MyIsAM:共享锁、独占锁
- InnoDB:共享锁、排它锁
- 读写锁、间隙锁(对匹配行的左右加锁)、自增锁
- 优化数据访问
- 减少数据访问(业务不需要的数据不要去访问),例如不使用select *
- 减少不需要访问的数据行,limit值多大可能导致需要全表扫描
- 减少请求不需要的数据
- 查询了不需要的数据
- 多表关联查询出了所有列
- 查询重复的数据(重复查询的数据建议缓存)
- 执行过程的优化
- 查询缓存:8之后去除
- 查询优化处理
- 语法解析器与预处理优化
- 查询优化器
- 数据查询页数统计(show status like 'last_query_cost')
- 每个表或索引的页面数
- 索引的基数,会影响索引的选择
- 索引和数据行的长度(可以采用前缀部分组建索引)
- 索引的分布情况
- 选择正确的执行计划
- 统计信息不正确导致执行计划选择错误
- mysql默认采用成本估算,这个成本估算可能和实际执行效率相差甚远
- 并发场景下查询问题
- mysql不会考虑不受其监控的操作成本
- 优化策略
- 静态:根据执行计划调整,比如将type优化成const
- 动态:与表的数据量或者索引的基数等等相关,会影响实际优化器的效果,这类的优化器比较不稳定,会随着数据量而变化
- 优化类型
- 尽量使用内连接代替外连接
- 尽量使用简短的等价语句代替,比如mysql自己优化的方式join on中的连接字段就会自动传递到另一个关联表;比如使用using代替on或自动过滤掉一个另一个关联列;比如使用in会只有一次判断,而没有多次遍历判断
- count、min、max等聚合函数如果命中索引,可以优化(比如min,直接取最左端;max,取最右端)
- 如果子查询表只有一行,则会自动优化为常量值;mysql有很多类似的优化,比如恒定为true的表达式会替换成true,没有实际效果的表达式也会被消除
- 索引覆盖,查询的列都建立在全值索引中
- 子查询优化:尽量命中与主句相同的优化策略,比如命中索引覆盖也可应用在子查询中
- 关联查询:优先使用内连接,内连接一般采用匹配原则,不会展示所有数据
- 排序优化:
- 避免文件排序,尽量命中索引优化,主键索引会更快
- order by 主键ID,可以使用主键扫描
- 优化特定类型的查询
- count:
- mysql中 count(1)和count(*)没差别
- 可以使用近似值,比如统计好字段,计入缓存,缓存定时更新
- 关联
- 尽量使用外键关联,或者有索引的列进行关联
- 尽量使用内连接代替外连接,一般不需要自行指定内连接的表顺序,mysql自动优化可能更好
- 尽量在关联查询的order by中只使用一个表的列,使得索引可以被使用
- 子查询
- 尽量使用join代替,因为子查询通常意味着临时表
- 可以将热点数据缓存起来,使用缓存来代替子查询(如先将in的子句id查询出来)
- limit
- 尽量使用覆盖查询
- 可以使用索引字段order by
- union
- 尽量使用union all,避免自动加上distinct影响性能
- 自定义变量:set varName:=value
- 可以应用在排名查询(mysql 8之后支持开窗函数可以直接用于排名)
-
相关阅读:
BZOJ_4320_ShangHai2006 Homework_分块
BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集
BZOJ_2788_[Poi2012]Festival_差分约束+tarjan+floyed
BZOJ_2795_[Poi2012]A Horrible Poem_hash+暴力
BZOJ_1598_[Usaco2008 Mar]牛跑步_A*
[转载]java匿名对象
[转载]static in Java
Bat批处理文件入门
在set中放入自定义类型
[转载]C++STL概述
-
原文地址:https://www.cnblogs.com/gabin/p/13723349.html
Copyright © 2020-2023
润新知