在Oracle数据库优化工作中,CURSOR_SHARING参数的调整是减少硬解析的常用手段,但参数修改后SQL文本的变化会让原本的执行计划固化规则失效。此时STORED OUTLINE就能发挥作用,即使SQL文本格式改变,也能强制使用指定的执行计划。

CURSOR_SHARING对SQL文本的影响
CURSOR_SHARING参数有三个可选值:EXACT、SIMILAR、FORCE。默认值为EXACT,此时SQL语句必须完全匹配才能共享游标。当设置为SIMILAR或FORCE时,Oracle会把SQL中的字面量替换为绑定变量,导致SQL文本发生变化。
例如原本的SQL是:
SELECT * FROM t_user WHERE id = 100;
当CURSOR_SHARING设置为FORCE后,SQL文本会变成:
SELECT * FROM t_user WHERE id = :"SYS_B_0";
这种变化会让原本基于原始SQL文本创建的执行计划固化规则无法匹配新的SQL,导致固化失效。
STORED OUTLINE的核心原理
STORED OUTLINE是Oracle提供的执行计划固化机制,它会将SQL的执行计划以大纲的形式存储起来,当相同的SQL(或经过CURSOR_SHARING转换后的SQL)执行时,优化器会优先使用大纲中存储的执行计划,而不是重新生成。
它的优势在于可以匹配经过CURSOR_SHARING转换后的SQL:当创建大纲时如果已经处于CURSOR_SHARING非EXACT的状态,那么大纲会记录转换后的SQL文本,后续即使SQL以字面量形式传入,经过转换后也能匹配到对应的大纲。
使用STORED OUTLINE固化执行计划的步骤
1. 确认当前CURSOR_SHARING参数
先查看当前数据库的CURSOR_SHARING设置,确保处于你需要固化执行计划的参数状态下操作:
SHOW PARAMETER CURSOR_SHARING; -- 或者查询数据字典 SELECT name, value FROM v$parameter WHERE name = 'cursor_sharing';
2. 创建STORED OUTLINE
如果需要为某条SQL固化执行计划,首先让这条SQL在目标CURSOR_SHARING状态下执行一次,生成对应的游标,然后创建大纲:
-- 先执行目标SQL,确保游标生成 SELECT /*+ TEST_OUTLINE */ * FROM t_user WHERE id = 100; -- 创建大纲,指定大纲名称 CREATE OUTLINE outline_t_user_id FOR CATEGORY test_outline ON SELECT /*+ TEST_OUTLINE */ * FROM t_user WHERE id = 100;
这里的CATEGORY可以自定义,方便后续管理不同类型的大纲。
3. 验证大纲是否创建成功
可以查询数据字典确认大纲的存在和状态:
SELECT name, category, sql_text, enabled FROM dba_outlines WHERE name = 'OUTLINE_T_USER_ID';
4. 启用大纲并使用
默认创建的大纲是启用的,如果需要手动启用,可以执行:
ALTER OUTLINE outline_t_user_id ENABLE;
之后执行对应的SQL,优化器就会使用大纲中存储的执行计划。可以通过查看执行计划验证是否生效:
EXPLAIN PLAN FOR SELECT /*+ TEST_OUTLINE */ * FROM t_user WHERE id = 100; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
执行计划的Note部分会显示使用了对应的outline。
注意事项
- STORED OUTLINE是Oracle较早期的功能,在12c及之后版本更推荐使用SQL Plan Management(SPM),但STORED OUTLINE在旧版本中依然稳定可用。
- 创建大纲时,必须保证当前的CURSOR_SHARING参数和后续业务运行时的参数一致,否则可能出现大纲不匹配的情况。
- 如果修改了CURSOR_SHARING参数,需要重新检查大纲的匹配情况,必要时重新创建大纲。
- 大纲过多会影响优化器的匹配效率,建议定期清理不再使用的大纲。
常见问题解答
大纲创建后不生效怎么办
首先检查大纲是否处于启用状态,然后确认执行的SQL是否和创建大纲时的SQL在CURSOR_SHARING转换后完全一致,可以通过查询v$sql视图查看当前游标的SQL文本,对比是否匹配大纲中的sql_text。
能否批量创建大纲
可以通过查询v$sql视图获取所有需要固化的SQL,然后批量生成创建大纲的语句,再执行创建操作,注意给每个大纲设置清晰的名称方便管理。
OracleSTORED_OUTLINECURSOR_SHARING执行计划固化修改时间:2026-06-01 22:58:48