Oracle SQL 优化器原理
Oracle SQL 优化器原理
适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
SQL 优化器(CBO)是执行计划生成器[1]:
类型:
- RBO(Rule-Based Optimizer):废弃
- CBO(Cost-Based Optimizer):默认
详细见:Oracle 优化器 CBO 原理。
2. 优化过程
2.1 步骤
1. 解析(Parse)
2. 优化(Optimize)
3. 行源生成(Row Source Generation)
4. 执行(Execute)
5. 取数据(Fetch)
2.2 解析
- 语法检查
- 语义检查
- 共享池检查
2.3 优化
- 逻辑转换
- 物理选择
- 成本计算
3. CBO 成本
3.1 成本组成
Cost = CPU Cost + I/O Cost
3.2 影响因素
- 表统计
- 索引统计
- 列统计
- 系统统计
- 参数
3.3 查看
EXPLAIN PLAN FOR SELECT ...;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
4. 逻辑转换
4.1 视图合并
SELECT * FROM (SELECT * FROM employees WHERE dept_id = 10) v
WHERE v.salary > 5000;
-- 转换为
SELECT * FROM employees WHERE dept_id = 10 AND salary > 5000;
4.2 子查询展开
SELECT * FROM employees
WHERE dept_id IN (SELECT id FROM departments WHERE location = 'NY')
-- 转换为 JOIN
4.3 谓词推进
SELECT * FROM (
SELECT * FROM employees
) v
WHERE v.dept_id = 10
-- 谓词推入
4.4 OR 展开
SELECT * FROM t WHERE id = 1 OR id = 2
-- 转换
SELECT * FROM t WHERE id = 1
UNION ALL
SELECT * FROM t WHERE id = 2
5. 统计信息
5.1 表统计
- num_rows
- blocks
- avg_row_len
5.2 列统计
- num_distinct
- density
- num_nulls
- histogram
5.3 索引统计
- blevel
- leaf_blocks
- distinct_keys
- clustering_factor
详细见:Oracle 直方图与统计信息。
6. 基数估算
6.1 公式
单表基数 = num_rows * selectivity
selectivity = 1 / num_distinct (无直方图)
6.2 直方图
- Frequency
- Height Balanced
- Hybrid(12c+)
6.3 影响
- JOIN 方法
- 索引选择
- 排序
7. JOIN 方法
7.1 Nested Loop
- 适合小结果集
- 索引友好
- 顺序 I/O
7.2 Hash Join
- 适合大结果集
- 内存要求
- 等值 JOIN
7.3 Sort Merge Join
- 适合大数据
- 非等值 JOIN
- 排序开销
详细见:Oracle JOIN 连接方式。
8. 访问路径
8.1 全表扫描
- 多块读
- 适合大比例
8.2 索引扫描
- 单块读
- 适合小比例
- 索引唯一/范围/扫描
8.3 快速全索引扫描
- 多块读
- 索引覆盖
详细见:Oracle 索引优化策略。
9. 优化器参数
9.1 optimizer_mode
ALTER SYSTEM SET optimizer_mode = ALL_ROWS;
-- ALL_ROWS / FIRST_ROWS_n
9.2 cursor_sharing
ALTER SYSTEM SET cursor_sharing = EXACT;
9.3 optimizer_features_enable
ALTER SYSTEM SET optimizer_features_enable = '19.1.0';
详细见:Oracle 数据库参数调优。
10. 自适应优化
10.1 Adaptive Plans(12c+)
- 执行时调整
- NL ↔ Hash
10.2 Adaptive Statistics
- 12.1 默认启用
- 12.2 默认禁用
10.3 Adaptive Cursor Sharing
- 绑定变量窥视
- 多计划
11. Hint
/*+ INDEX(table idx) */ -- 索引
/*+ FULL(table) */ -- 全表
/*+ USE_HASH(a b) */ -- Hash Join
/*+ LEADING(a b) */ -- 顺序
/*+ PARALLEL(table 8) */ -- 并行
详细见:Oracle 优化器 Hint 详解。
12. 执行计划
12.1 查看
EXPLAIN PLAN FOR ...;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY));
-- 实际
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id'));
-- AWR
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('&sql_id'));
详细见:Oracle 执行计划详解。
12.2 关注
- Cost
- Cardinality
- 估算 vs 实际
- I/O
13. 10053 事件
13.1 启用
ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';
EXPLAIN PLAN FOR ...;
ALTER SESSION SET EVENTS '10053 trace name context off';
13.2 分析
# trace 文件
# 优化器决策过程
# 成本计算
14. 常见坑与排错
14.1 选错计划
-- 1. 统计信息
EXEC DBMS_STATS.GATHER_TABLE_STATS(...);
-- 2. 直方图
-- 3. SQL Profile
-- 4. SQL Plan Baseline
14.2 计划不稳定
-- 1. SQL Plan Baseline
-- 2. 绑定变量窥视
-- 3. Adaptive Features
15. 最佳实践
- 统计信息:基础
- 直方图:数据倾斜
- SQL Plan Baseline:稳定
- HINT 谨慎:必要时
- 执行计划分析:根因
- 10053 深度:诊断
- Adaptive 谨慎:12c+
- 绑定变量:减少解析
- 测试验证:效果
- 文档化:记录
16. 参考资料
[1] Oracle Database SQL Tuning Guide 19c, “Optimizer” https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/optimizer.html