Oracle数据库的cursor_sharing参数用于控制SQL语句的共享行为,它有三个可选取值exact、similar、force,不同取值会直接影响SQL的解析方式、共享效率以及执行性能,理解三者的区别对数据库性能优化有重要意义。

cursor_sharing参数基础概念
在Oracle中,每条SQL语句执行前都需要经过解析阶段,解析分为硬解析和软解析。硬解析需要完成语法检查、语义检查、生成执行计划等完整流程,消耗大量CPU和共享池资源;软解析则是直接复用共享池中已有的执行计划,开销极低。cursor_sharing参数的作用就是决定Oracle如何处理SQL中的字面量,从而影响SQL能否被共享、是否需要硬解析。
三个取值的核心区别
1. exact(默认值)
当cursor_sharing设置为exact时,Oracle不会主动替换SQL中的字面量,只有当两条SQL语句文本完全一致时,才会共享游标。比如下面两条SQL,即使逻辑相同,也会被认为是不同的SQL,分别进行硬解析:
-- 第一条SQL SELECT * FROM emp WHERE deptno = 10; -- 第二条SQL SELECT * FROM emp WHERE deptno = 20;
这种方式的优点是执行计划完全匹配当前SQL的字面量,不会出现执行计划不匹配的问题,适合OLTP系统中SQL固定、字面量重复率低的场景。缺点是如果应用大量使用不同字面量的相同逻辑SQL,会产生大量硬解析,浪费共享池资源,甚至可能引发共享池争用问题。
2. similar
设置为similar时,Oracle会将SQL中的字面量替换为系统生成的绑定变量,尝试共享游标。但如果字面量的值可能影响执行计划,Oracle会认为原有游标不可用,仍然会进行硬解析。比如对于存在直方图的字段,不同字面量可能对应不同的数据分布,此时即使SQL结构相同,也会重新解析生成执行计划。
这种取值的初衷是平衡共享和性能,既减少不必要的硬解析,又避免不合适的执行计划被复用。但在实际使用中,similar的行为比较复杂,Oracle官方也不推荐在生产环境长期使用,在12c之后的版本中该取值已经被标记为废弃,不建议再使用。
3. force
force取值下,Oracle会强制将所有SQL中的字面量替换为绑定变量,只要SQL结构一致就直接共享游标,不会考虑字面量是否会影响执行计划。比如上面的两条查询deptno的SQL,会被统一替换为如下形式,直接复用已有的游标:
SELECT * FROM emp WHERE deptno = :sys_b_0;
这种方式的优点是能最大程度减少硬解析,适合OLAP或者大量重复逻辑、不同字面量的SQL场景。缺点是如果字段数据分布不均匀,可能会出现执行计划不匹配的问题,比如deptno=10的数据只有10行,deptno=20的数据有10000行,复用同一个执行计划可能导致性能下降。
三者对比总结
我们可以通过下面的表格更清晰地看到三者的差异:
| 参数取值 | 字面量处理方式 | 游标共享条件 | 适用场景 | 潜在风险 |
|---|---|---|---|---|
| exact | 不替换字面量 | SQL文本完全一致 | OLTP系统,SQL固定 | 大量不同字面量SQL会导致硬解析过多 |
| similar | 替换字面量,考虑执行计划影响 | 结构一致且字面量不影响执行计划 | 官方不推荐生产使用 | 行为复杂,后续版本已废弃 |
| force | 强制替换所有字面量为绑定变量 | SQL结构一致即可 | 大量重复逻辑SQL的场景 | 可能出现执行计划不匹配的性能问题 |
生产环境设置建议
大部分常规OLTP系统建议保持默认的exact取值,同时规范应用开发,尽量使用绑定变量代替字面量,从根源上减少硬解析。如果应用中确实存在大量无法修改的字面量SQL,且数据分布比较均匀,可以临时设置force来减少硬解析,但需要监控SQL执行性能,及时发现执行计划不匹配的问题。similar取值不建议在任何生产环境中使用,避免不可预期的解析行为影响数据库稳定性。
修改cursor_sharing参数可以使用如下SQL,修改后需要重启数据库才能生效:
-- 会话级别修改,仅当前会话生效 ALTER SESSION SET cursor_sharing = force; -- 系统级别修改,需要重启数据库 ALTER SYSTEM SET cursor_sharing = exact SCOPE = SPFILE;
cursor_sharingOracleSQL共享硬解析软解析修改时间:2026-06-04 02:27:16