Oracle SQL 解析与执行过程

Oracle SQL 解析与执行过程

适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

理解 SQL 解析与执行过程助于优化[1]:

详细见:Oracle 优化器 CBO 原理


2. 处理流程

2.1 阶段

1. 解析(Parse)
   - 语法检查
   - 语义检查
   - 共享池检查
   - 优化
2. 执行(Execute)
3. 获取(Fetch)

2.2 流程

SQL → 解析 → 执行计划 → 执行 → 结果

3. 解析

3.1 语法检查

- SQL 语法
- 关键字
- 顺序

3.2 语义检查

- 对象存在
- 权限
- 列存在
- 类型

3.3 共享池检查

- Library Cache
- SQL 文本 hash
- 匹配
- 软解析 / 硬解析

4. 硬解析

4.1 触发

- 首次执行
- SQL 文本不同
- 统计变化
- Shared Pool 不足

4.2 过程

1. 语法/语义
2. 优化
   - CBO
   - 统计信息
   - 生成执行计划
3. 存储
   - Library Cache
4. 执行

4.3 开销

- CPU
- Latch
- Library Cache
- 高

5. 软解析

5.1 过程

1. 语法/语义
2. 共享池匹配
3. 直接执行

5.2 优化

- 绑定变量
- Session Cached Cursors
- CURSOR_SHARING

6. 优化

6.1 CBO

- 基于成本
- 统计信息
- 计划生成
- 最低成本

6.2 成本

- CPU
- I/O
- 网络
- 内存

6.3 统计

EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'EMPLOYEES', cascade => TRUE);
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('SCOTT');

详细见:Oracle 直方图与统计信息


7. 执行计划

7.1 生成

EXPLAIN PLAN FOR SELECT ...;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY));

7.2 缓存

SELECT sql_id, child_number, plan_hash_value, executions
FROM v$sql
WHERE sql_text LIKE '...';

7.3 固定

-- Baseline
EXEC DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id => '...');

详细见:Oracle SQL Plan Baseline 基线


8. 执行

8.1 步骤

1. 私有 SQL 区
2. 执行计划
3. 数据访问
4. 操作

8.2 操作

- TABLE ACCESS
- INDEX ACCESS
- JOIN
- SORT
- AGGREGATE
- FILTER

详细见:Oracle 执行计划详解


9. Fetch

9.1 行源

- 行源生成器
- 迭代器
- 数据流

9.2 数组

- 批量
- 网络往返
- 性能

10. 共享池

10.1 Library Cache

- SQL/PLSQL
- 执行计划
- LRU

10.2 Data Dictionary Cache

- 对象信息
- 权限

10.3 查看

SELECT namespace, gets, gethits, pins, pinhits
FROM v$librarycache;

11. PGA

11.1 私有 SQL 区

- 绑定变量值
- 运行时内存
- 排序
- 哈希

11.2 UGA

- 会话状态
- 游标

详细见:Oracle 内存调优 SGA PGA


12. 绑定变量

12.1 优势

- 减少 hard parse
- Shared Pool 高效
- 性能

12.2 使用

-- PL/SQL 自动
EXECUTE IMMEDIATE 'SELECT * FROM t WHERE id = :id' USING v_id;

-- Java
PreparedStatement ps = con.prepareStatement("SELECT * FROM t WHERE id = ?");
ps.setInt(1, 100);

详细见:Oracle PL/SQL 动态 SQL 详解


13. CURSOR_SHARING

13.1 模式

ALTER SESSION SET cursor_sharing = EXACT;      -- 默认
ALTER SESSION SET cursor_sharing = FORCE;      -- 强制
ALTER SESSION SET cursor_sharing = SIMILAR;    -- 智能已废弃

13.2 FORCE

- 自动替换字面量为绑定
- 减少 hard parse
- 可能影响优化

14. Session Cached Cursors

ALTER SESSION SET session_cached_cursors = 100;
-- 缓存关闭的游标
- 软软解析
- 性能

15. 监控

15.1 解析统计

SELECT name, value 
FROM v$sysstat 
WHERE name LIKE '%parse%';

-- parse count (hard)
-- parse count (total)
-- parse time elapsed

15.2 高硬解析

SELECT sql_text, parse_calls, executions
FROM v$sql
WHERE parse_calls > 100
ORDER BY parse_calls DESC FETCH FIRST 10 ROWS ONLY;

15.3 Library Cache

SELECT namespace, gets, gethits, gethitratio
FROM v$librarycache;

16. AWR

16.1 报告

Load Profile
- Parses
- Hard parses
- Soft parses

详细见:Oracle AWR 详解


17. 优化

17.1 减少 hard parse

- 绑定变量
- CURSOR_SHARING = FORCE(兜底)
- Session Cached Cursors
- 共享 SQL

17.2 统计信息

- 收集
- 直方图
- 扩展

17.3 Shared Pool

- 大小
- 保留
- 清理

详细见:Oracle 内存调优 SGA PGA


18. 常见问题

18.1 ORA-04031

- Shared Pool 不足
- 绑定变量
- 增大

18.2 High Hard Parse

- 字面量 SQL
- CURSOR_SHARING
- 应用改造

18.3 Library Cache Lock

- 解析锁
- 长事务
- 重编译

19. 最佳实践

  1. 绑定变量:必须
  2. Session Cached Cursors:性能
  3. 统计信息:更新
  4. 执行计划:稳定
  5. Baseline:固定
  6. 监控:解析
  7. Shared Pool:充足
  8. 避免重编译:稳定
  9. PL/SQL:自动绑定
  10. 测试:验证

20. 参考资料

[1] Oracle Database Concepts 19c, “SQL Processing” https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/sql.html