切换Oracle优化器的方式
【摘要】 在Oracle数据库中,可以通过修改参数OPTIMIZER_MODE来切换优化器模式,该参数控制优化器在生成执行计划时采用**基于规则(RBO)还是基于成本(CBO)**的策略。以下是详细操作步骤和注意事项: 一、优化器模式类型RULE使用Oracle早期预设的15条访问路径规则(如索引优先于全表扫描)。已弃用:Oracle 10g后默认禁用,仅用于兼容旧应用。示例规则:单列索引优先于复合索...
在Oracle数据库中,可以通过修改参数OPTIMIZER_MODE
来切换优化器模式,该参数控制优化器在生成执行计划时采用**基于规则(RBO)还是基于成本(CBO)**的策略。以下是详细操作步骤和注意事项:
一、优化器模式类型
-
RULE
- 使用Oracle早期预设的15条访问路径规则(如索引优先于全表扫描)。
- 已弃用:Oracle 10g后默认禁用,仅用于兼容旧应用。
- 示例规则:
- 单列索引优先于复合索引。
- 全表扫描的优先级低于任何索引扫描。
-
FIRST_ROWS
- 基于成本,但优先返回首行数据(适合OLTP系统,强调低延迟)。
- 可能选择嵌套循环连接(Nested Loops)等快速返回结果的计划。
- 子选项:
FIRST_ROWS_1
:优化返回首1行。FIRST_ROWS_10
/100
/1000
:优化返回首N行。
-
FIRST_ROWS_N
(Oracle 12c+)- 替代旧版
FIRST_ROWS
,更精细控制返回首批行的优化目标。
- 替代旧版
-
ALL_ROWS
(默认)- 基于成本,优化整体查询吞吐量(适合数据仓库,强调资源高效利用)。
- 可能选择哈希连接(Hash Join)或全表扫描等高吞吐量计划。
二、切换优化器模式的方法
1. 会话级修改(临时生效)
-- 查看当前会话的优化器模式
SHOW PARAMETER optimizer_mode;
-- 修改当前会话的优化器模式(仅对当前连接有效)
ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS;
-- 或
ALTER SESSION SET OPTIMIZER_MODE = ALL_ROWS;
2. 系统级修改(永久生效)
-- 修改参数文件(SPFILE或PFILE)并重启数据库
-- 1. 编辑SPFILE(需DBA权限)
ALTER SYSTEM SET OPTIMIZER_MODE = FIRST_ROWS SCOPE=SPFILE;
-- 2. 重启数据库使更改生效
SHUTDOWN IMMEDIATE;
STARTUP;
SCOPE
选项:MEMORY
:仅修改当前实例(重启后失效)。SPFILE
:修改参数文件(需重启)。BOTH
:同时修改内存和参数文件(需重启)。
3. 使用SQL提示(Hint)强制指定
在SQL语句中通过提示覆盖会话或系统级设置:
-- 强制使用FIRST_ROWS模式
SELECT /*+ FIRST_ROWS */ * FROM employees WHERE salary > 5000;
-- 强制使用ALL_ROWS模式
SELECT /*+ ALL_ROWS */ * FROM large_table WHERE dept_id = 10;
三、验证优化器模式
-
查看当前模式
SELECT name, value, display_value FROM v$parameter WHERE name = 'optimizer_mode';
-
分析执行计划
使用EXPLAIN PLAN
或DBMS_XPLAN
查看优化器选择的计划是否符合预期:EXPLAIN PLAN FOR SELECT * FROM employees WHERE dept_id = 10; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
- 关键指标:
Operation
(如TABLE ACCESS FULL
、INDEX RANGE SCAN
)。Cost
(成本值,模式不同可能导致成本估算差异)。Cardinality
(估算行数,反映选择性计算方式)。
- 关键指标:
四、切换优化器模式的注意事项
-
兼容性问题
RULE
模式已过时,可能导致性能下降或错误(如无法利用新特性如并行查询)。- 仅在迁移旧应用时临时使用,建议最终迁移到CBO。
-
性能影响
- OLTP系统:优先使用
FIRST_ROWS
以减少响应时间。 - 数据仓库:使用
ALL_ROWS
以最大化吞吐量。 - 混合负载:通过提示(Hint)或SQL Profile针对特定SQL优化。
- OLTP系统:优先使用
-
统计信息依赖
- CBO模式(
FIRST_ROWS
/ALL_ROWS
)依赖准确的统计信息。 - 确保定期收集统计信息:
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA_NAME', 'TABLE_NAME');
- CBO模式(
-
动态采样
- 对未分析的表,CBO可能启用动态采样(
OPTIMIZER_DYNAMIC_SAMPLING
)。 - 调整采样级别(0-11)以平衡估算精度和开销。
- 对未分析的表,CBO可能启用动态采样(
-
参数冲突
- 避免同时设置冲突参数(如
OPTIMIZER_INDEX_COST_ADJ
和FIRST_ROWS
),可能导致优化器决策混乱。
- 避免同时设置冲突参数(如
五、示例场景
场景1:OLTP系统优化响应时间
-- 会话级切换到FIRST_ROWS
ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS;
-- 执行查询(优化器优先选择快速返回结果的计划)
SELECT /*+ INDEX(e idx_emp_salary) */ *
FROM employees e
WHERE salary > 5000
AND ROWNUM < 10;
场景2:数据仓库优化吞吐量
-- 系统级切换到ALL_ROWS(需DBA权限)
ALTER SYSTEM SET OPTIMIZER_MODE = ALL_ROWS SCOPE=SPFILE;
-- 重启后执行大表聚合查询
SELECT dept_id, AVG(salary)
FROM employees
GROUP BY dept_id;
总结
- 推荐模式:Oracle 12c+默认使用
ALL_ROWS
(CBO),适合大多数场景。 - 临时调整:通过会话级设置或SQL提示快速验证不同模式的效果。
- 长期策略:结合统计信息管理、SQL调优和参数配置(如
PGA_AGGREGATE_TARGET
)综合优化性能。 - 避免误区:不要盲目切换模式,需通过执行计划分析实际性能差异。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)