目录
- 一、执行计划:SQL的导航仪
- 1.1 导航仪是啥?点外卖秒懂!
- 二、统计信息:路况实时更新
- 2.1 为什么需要路况?
- 2.2 如何更新路况?
- 三、5招获取执行计划:小白必备
- 四、3分钟破解执行计划密码
- 4.1 关键字段速查表
- 4.2 看执行顺序口诀
- 五、实战:揪出SQL中的“堵车王”
- 5.1 案例:索引失效的“鬼打墙”
- 5.2 案例:连接顺序引发“大塞车”
- 六、闯关挑战:测测你的优化段位
- 七、新手村→王者进阶指南
- 7.1 学习路线图
摘要:刚写好的SQL跑起来比蜗牛还慢?别删库跑路!本文将用点外卖、导航等生活例子,带你轻松看懂SQL执行计划,附赠【优化宝典】和互动习题,包教包会!
一、执行计划:SQL的导航仪
1.1 导航仪是啥?点外卖秒懂!
假设你要点外卖,数据库就是外卖小哥,执行计划就是他选择的路线:
- 路线A:先取奶茶再拿炸鸡(顺序扫描)
- 路线B:直接去综合商场一次拿齐(索引扫描)
SQL示例:
SELECT * FROM 外卖订单 WHERE 商家='奶茶店' AND 状态='已完成';
✅ 高效计划:用商家索引
快速定位奶茶店订单,再过滤状态
❌ 低效计划:扫描所有订单,一个个检查商家和状态(全表扫描)
二、统计信息:路况实时更新
2.1 为什么需要路况?
外卖小哥要知道:
- 奶茶店今天订单量(表行数)
- 不同商家的分布区域(数据分布)
2.2 如何更新路况?
自动更新(推荐夜间自动进行):
-- Oracle自动任务
BEGIN
DBMS_STATS.GATHER_SCHEMA_STATS('外卖平台');
END;
手动更新(紧急修路):
-- 针对大表采样20%数据
EXEC DBMS_STATS.GATHER_TABLE_STATS('外卖平台', '订单表', estimate_percent=>20);
⚠️ 警告:别在午高峰更新!否则小哥会被卡在店里(锁表阻塞)
三、5招获取执行计划:小白必备
招式 | 适用场景 | 操作步骤(Oracle为例) |
---|---|---|
EXPLAIN | 纸上谈兵 | EXPLAIN PLAN FOR SELECT ... |
AUTOTRACE | 看执行报告 | SET AUTOTRACE TRACEONLY |
DBMS_XPLAN | 查历史SQL | SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id')) |
10046 Trace | 侦探模式 | ALTER SESSION SET EVENTS '10046 trace name context forever, level 12'; |
AWR报告 | 对比历史堵车记录 | 运行@?/rdbms/admin/awrsqrpt.sql |
四、3分钟破解执行计划密码
4.1 关键字段速查表
字段 | 解读 | 危险信号 |
---|---|---|
Operation | 操作类型 | FULL SCAN 出现次数多 |
Starts | 执行次数 | 数值大≈绕远路 |
A-Rows/E-Rows | 实际/预估行数 | 差异大→统计信息过期 |
Cost | 优化器预估成本 | 数值越高越慢 |
4.2 看执行顺序口诀
“先右后左,先下后上”
示例计划:
NESTED LOOPS
INDEX SCAN 商家索引 -- 第1步:先执行右边
TABLE ACCESS 订单表 -- 第2步:再执行左边
💡 就像外卖小哥先找奶茶店(索引),再取具体订单(表访问)
五、实战:揪出SQL中的“堵车王”
5.1 案例:索引失效的“鬼打墙”
问题SQL:
SELECT * FROM 用户表 WHERE 年龄 BETWEEN 20 AND 30;
执行计划:
TABLE ACCESS FULL 用户表
🔍 诊断:
- 预期:走
年龄索引
快速定位 - 实际:全表扫描10万行!
病因:年龄在20-30的用户占了40%,优化器觉得全表更快!
💊 药方:强制使用索引(慎用!):
SELECT /*+ INDEX(用户表 年龄索引) */ ...
5.2 案例:连接顺序引发“大塞车”
问题SQL:
SELECT * FROM 订单表 o JOIN 用户表 u ON o.user_id = u.id;
执行计划:
HASH JOIN
TABLE ACCESS FULL 用户表 -- 先扫描100万用户
TABLE ACCESS FULL 订单表 -- 再扫描500万订单
🚦 堵点:两个大表全扫描,内存撑爆!
🚀 优化:先过滤再关联:
SELECT *
FROM (SELECT * FROM 订单表 WHERE 状态='已完成') o
JOIN 用户表 u ON o.user_id = u.id;
六、闯关挑战:测测你的优化段位
-
题目:执行计划中出现
SORT ORDER BY
且耗时高,应该怎么办?
A. 加内存 B. 删排序 C. 用索引
答案:C(创建排序字段的索引,避免物理排序) -
题目:哪个现象说明统计信息不准?
A. E-Rows=100,A-Rows=105
B. E-Rows=100,A-Rows=10000
答案:B(实际行数远大于预估)
七、新手村→王者进阶指南
7.1 学习路线图
- 青铜:《SQL必知必会》、LeetCode简单题
- 白银:《高性能MySQL》、AWR报告分析
- 王者:执行计划绑定、SQL重写规则
🎯下期预告:《操控SQL优化技巧》
💬互动话题:你在学习SQL时遇到过哪些坑?欢迎评论区留言讨论!
🏷️温馨提示:我是[随缘而动,随遇而安], 一个喜欢用生活案例讲技术的开发者。如果觉得有帮助,点赞关注不迷路🌟