测验:查询调优与执行计划
如何正确理解执行计划中的 cost 值?
- 它是以毫秒为单位的预计执行时间,数值就是耗时
- 它是把页面顺序读取设为 1.0 的相对分数,不能用绝对阈值判断风险
- 它表示优化器实际决定读取的行数
- 它以 MB 为单位估算查询所需的工作内存
执行计划预计 1 行,实际却有 480,000 行。首先应该做什么?
- 给查询添加连接提示和索引提示,强制得到想要的计划
- 删除使优化器困惑的索引,减少选择
- 刷新统计信息——优化器是在错误前提上计算的
- 行数太多,应对表分区以缩小扫描范围
执行计划显示 Hash Join 为 131ms,其子节点 Seq Scan 为 92ms。连接本身消耗了多少时间?
- 131ms——节点标出的时间就是该节点自身耗时
- 不超过约 39ms——父节点时间包含子节点的累计时间
- 223ms——父子节点时间相加才是总耗时
- 92ms——读取真实数据的子节点就是连接成本
为什么 WHERE substr(ORD_DT,1,6) = '202608' 无法使用索引?
- 每行都要调用 substr,成本高于索引查找
- 字符串比较受排序规则影响,无法使用索引顺序
- 索引按列的原始值排序,套用函数后无法利用该顺序
- 优化器无法把含函数的条件折叠为常量,这是已知限制
在执行计划中看到 Seq Scan(全表扫描)时,正确态度是什么?
- 全表扫描表示读取量大,应为该条件创建索引
- 这说明条件写法使优化器无法使用索引,应重写查询
- 如果表很小或查询要读取大多数行,它可能就是最佳方案,应结合情况判断
- 一定是统计过期导致误选,应先刷新统计再看
为什么仅查看日志很难发现 N+1 问题?
- ORM 内部生成的查询不会写入应用日志
- 延迟加载查询在不同线程执行,日志分散
- 每条查询都很快,看起来没有问题,但往返次数会随数据量增长
- N+1 只体现在执行计划中,查询日志不留痕迹
数据迁移后性能突然下降,常见原因是什么?
- 统计信息未刷新——查询和索引不变,却因旧统计导致计划错误
- 迁移流量占满线路,应用请求也被拖延
- 大量插入使文件碎片化,顺序读取变慢
- 迁移工具持续占用连接,连接池没有余量