Oracle AskTOM 经典问答集

Oracle AskTOM 经典问答集

来源:AskTOM (asktom.oracle.com) 适用版本:Oracle Database 全版本 文档版本:v1.0 / 2026-07-22


1. 概述

AskTOM 由 Tom Kyte 于 2000 年创立,是 Oracle 官方问答栏目,汇集 20+ 年的经典问答[1]。

Tom Kyte 的核心理念:

  • “Why?” 比 “How?” 更重要
  • 理解原理胜过记住命令
  • 数据库应该做数据库擅长的事
  • 绑定变量、约束、完整性

2. 经典问答 1:绑定变量

2.1 问题

为什么我的 Oracle 数据库 CPU 使用率很高,但实际没多少数据?

2.2 Tom 回答要点

- 没有使用绑定变量
- 每条 SQL 都硬解析
- 解析消耗 CPU
- 库缓存争用

2.3 示例

-- 错误:未使用绑定变量
EXECUTE IMMEDIATE 'SELECT * FROM emp WHERE id=' || v_id;

-- 正确:使用绑定变量
EXECUTE IMMEDIATE 'SELECT * FROM emp WHERE id=:1' USING v_id;

2.4 验证

SELECT sql_text, executions, parse_calls 
FROM v$sql 
WHERE parse_calls > executions * 0.9;

详细见:Oracle-AskTOM绑定变量深度解析.md


3. 经典问答 2:Commit 频率

3.1 问题

我应该在循环里频繁 commit 吗?

3.2 Tom 回答要点

- 不要频繁 commit
- 每次 commit:
  - 写 Redo
  - 释放锁
  - 清理 Undo
- 频繁 commit 性能差
- 应该事务级 commit

3.3 性能对比

- 每行 commit:100 万行 → 数小时
- 事务级 commit:100 万行 → 数分钟
- 性能差 10-100 倍

详细见:Oracle-AskTOM-Commit提交机制详解.md


4. 经典问答 3:表 vs 视图

4.1 问题

表、视图、物化视图有什么区别?什么时候用什么?

4.2 Tom 回答要点

对象存储更新性能
实际存储实时直接
视图不存储实时计算查询展开
物化视图实际存储按需刷新预计算

4.3 选择

- 表:基础数据
- 视图:简化查询、安全
- 物化视图:汇总、报表

详细见:Oracle-AskTOM-表与视图与物化视图对比.md


5. 经典问答 4:外键约束

5.1 问题

外键约束有必要吗?应用层保证不就行了吗?

5.2 Tom 回回答要点

- 必须有外键约束
- 应用层无法 100% 保证
- 数据完整性是数据库职责
- 数据可能被其他途径修改

5.3 原则

- 能在数据库约束的,就在数据库
- 应用层是补充,不是替代
- 数据完整性 > 性能

6. 经典问答 5:分区表

6.1 问题

我的表很大(1 亿行),需要分区吗?

6.2 Tom 回答要点

- 分区不是性能银弹
- 分区解决的是管理问题
- 大表分区便于管理(删除、归档)
- 性能取决于分区消除
- 错误分区 → 性能更差

6.3 何时分区

- 表太大(2GB+)
- 按时间归档
- 按业务分区
- 维护窗口

详细见:Oracle-AskTOM-分区表最佳实践.md


7. 经典问答 6:索引

7.1 问题

索引越多越好吗?

7.2 Tom 回答要点

- 索引有代价
- DML 变慢
- 存储消耗
- 应该按查询设计
- 监控未使用索引

7.3 监控

ALTER INDEX emp_idx MONITORING USAGE;
-- 一段时间后
SELECT * FROM v$object_usage;

详细见:Oracle-AskTOM-索引策略问答.md


8. 经典问答 7:SQL 注入

8.1 问题

拼接 SQL 安全吗?

8.2 Tom 回答要点

- 绝对不安全
- SQL 注入风险
- 必须使用绑定变量
- 使用 DBMS_ASSERT

8.3 防护

-- DBMS_ASSERT
v_sql := 'SELECT * FROM emp WHERE ename=' || 
  SYS.DBMS_ASSERT.ENQUOTE_LITERAL(v_name);

9. 经典问答 8:临时表

9.1 问题

临时表和普通表有什么区别?

9.2 Tom 回答要点

- 临时表数据会话级
- 自动清理
- 不产生 Redo(少)
- 适合中间结果

9.3 类型

CREATE GLOBAL TEMPORARY TABLE temp_emp 
  ON COMMIT PRESERVE ROWS  -- 会话级
  AS SELECT * FROM emp WHERE 1=2;

10. 经典问答 9:PL/SQL vs SQL

10.1 问题

应该用 PL/SQL 还是纯 SQL?

10.2 Tom 回答要点

- 能用 SQL 就用 SQL
- PL/SQL 是补充
- SQL 集合操作效率高
- PL/SQL 适合复杂逻辑
- 不要逐行处理(slow-by-slow)

10.3 反例

-- 错误:逐行处理
FOR rec IN (SELECT * FROM emp) LOOP
  UPDATE emp SET salary = salary * 1.1 WHERE id = rec.id;
END LOOP;

-- 正确:集合操作
UPDATE emp SET salary = salary * 1.1;

11. 经典问答 10:NULL 处理

11.1 问题

NULL 怎么比较?

11.2 Tom 回答要点

- NULL 不等于 NULL
- 必须用 IS NULL
- NULL 影响聚合
- 三值逻辑

11.3 示例

-- 错误
SELECT * FROM emp WHERE commission = NULL;

-- 正确
SELECT * FROM emp WHERE commission IS NULL;

12. Tom Kyte 经典语录

- "How do I do X? Why would I want to do X?"
- "If you can do it in SQL, do it in SQL"
- "Bind variables are not optional"
- "Constraints are your friends"
- "The database is the castle"

13. AskTOM 学习方法

13.1 检索

- 按关键词搜索
- 按主题浏览
- 关注热门问答

13.2 验证

- 测试环境复现
- 验证观点
- 形成认知

13.3 思考

- 不仅 How,更要 Why
- 理解原理
- 建立思维

14. 最佳实践

  1. 绑定变量:必用
  2. 约束:必加
  3. SQL 优先:能 SQL 不 PL/SQL
  4. Commit:事务级
  5. 分区:按需
  6. 索引:监控
  7. 数据完整性:数据库保证
  8. 思考 Why:原理
  9. 测试:验证
  10. 溯源:原文

15. 参考资料

[1] AskTOM, https://asktom.oracle.com [2] Tom Kyte, “Expert One-on-One Oracle”, Apress, 2002 [3] Tom Kyte, “Expert Oracle Database Architecture”, Apress