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;
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+)
- 按时间归档
- 按业务分区
- 维护窗口
7. 经典问答 6:索引
7.1 问题
索引越多越好吗?
7.2 Tom 回答要点
- 索引有代价
- DML 变慢
- 存储消耗
- 应该按查询设计
- 监控未使用索引
7.3 监控
ALTER INDEX emp_idx MONITORING USAGE;
-- 一段时间后
SELECT * FROM v$object_usage;
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. 最佳实践
- 绑定变量:必用
- 约束:必加
- SQL 优先:能 SQL 不 PL/SQL
- Commit:事务级
- 分区:按需
- 索引:监控
- 数据完整性:数据库保证
- 思考 Why:原理
- 测试:验证
- 溯源:原文
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