第34期 CURSOR_SHARING和FORCE_MATCHING_SIGNATURE对SQL计划稳定性的局限性

来源:这里教程网 时间:2026-03-03 21:44:12 作者:

在 Oracle 数据库中, CURSOR_SHARING  参数和  FORCE_MATCHING_SIGNATURE  是用于优化 SQL 语句共享和执行计划稳定性的工具。然而,它们在某些情况下存在局限性,尤其是在处理复杂或动态生成的 SQL 语句时。本文将探讨这些局限性,并分析它们对 SQL 计划稳定性的影响。

CURSOR_SHARING=FORCE 的作用

CURSOR_SHARING=FORCE  是 Oracle 提供的一个参数,用于强制共享具有相似文本但字面值不同的 SQL 语句。它的主要目的是减少硬解析的次数,从而提高数据库的性能。

此外,相同的机制(在计算 SQL 哈希值以进行库缓存查找之前,将字面值替换为绑定变量占位符)也可以用于强制为仅字面值不同的 SQL 语句应用 SQL 配置文件。只需使用  DBMS_SQLTUNE.ACCEPT_PROFILE(…, FORCE_MATCH=>TRUE) 接受 SQL 配置文件即可。 然而,这种“强制匹配”有一个局限性,可能会使其在应用程序使用动态生成 SQL 的数据库中几乎无法实现计划稳定性。

如下面的示例:当cursor_sharing=EXACT默认值的情况下, SQL 语句不能被共享,要进行硬解析。

show parameter cursor_sharing
set linesize 10000
col SQL_TEXT for a100
col force_matching_signature for 999999999999999999999999999
SELECT * FROM dual WHERE rownum IN (1,2,3);
SELECT * FROM dual WHERE rownum IN (4,5,6);
SELECT sql_id,hash_value,force_matching_signature,sql_text FROM v$sql WHERE sql_text like '%SELECT * FROM dual%'order by sql_text;
SELECT sql_id,hash_value,force_matching_signature,sql_text FROM v$sql WHERE sql_id = (SELECT prev_sql_id FROM v$session WHERE sid = USERENV('SID'));

我们看到SELECT * FROM dual WHERE rownum IN (1,2,3);和SELECT * FROM dual WHERE rownum IN (4,5,6);的sql文本不能被共享, HASH_VALUE的值是不同的,但是FORCE_MATCHING_SIGNATURE的值是相同的。

在  CURSOR_SHARING=FORCE  的情况下,Oracle 会将它们视为相同的 SQL 语句,并使用相同的执行计划。 用于强制共享具有相似文本但字面值不同的 SQL 语句。它的主要目的是减少硬解析的次数,从而提高数据库的性能。

ALTER SESSION SET cursor_sharing = FORCE;
set linesize 10000
col SQL_TEXT for a100
col force_matching_signature for 999999999999999999999999999
SELECT * FROM dual WHERE rownum IN (1,2,3);
SELECT * FROM dual WHERE rownum IN (4,5,6);
SELECT sql_id,hash_value,force_matching_signature,sql_text FROM v$sql WHERE sql_text like '%SELECT * FROM dual%' order by sql_text;

我们看到字面值  1,2,3和4,5,6 被替换为 SQL 文本中的  :SYS_B_x  绑定变量。SQL 哈希值(以及  SQL_ID  和  force_matching_signature )是在此替换完成后计算的。因此两条sql的hash_value和forec_mathing_signature值是相同的。

CURSOR_SHARING=FORCE 的局限性

尽管  CURSOR_SHARING=FORCE 在某些场景下非常有用,但它也存在一些局限性:

    执行计划可能不最优:由于 Oracle 会将不同的字面值替换为绑定变量,这可能导致执行计划无法针对特定的字面值进行优化。例如,某些查询可能在小范围内扫描时效率更高,但在大范围内扫描时效率较低。如果使用绑定变量,优化器无法根据实际值选择最佳计划。

  1. 不适合所有 SQL 语句:对于某些复杂的 SQL 语句,尤其是包含动态 SQL 或复杂表达式的语句, CURSOR_SHARING=FORCE 可能会导致性能下降或执行计划不稳定。

  2. 无法解决所有硬解析问题:虽然  CURSOR_SHARING=FORCE 可以减少硬解析的次数,但它并不能完全消除硬解析。在某些情况下,仍然需要手动优化 SQL 语句或使用其他技术(如 SQL 计划基线)来确保执行计划的稳定性。

    FORCE_MATCHING_SIGNATURE 的作用

    FORCE_MATCHING_SIGNATURE 是 Oracle 提供的一个功能,用于识别具有相同结构但字面值不同的 SQL 语句。它通过计算 SQL 语句的签名来实现这一点,从而帮助数据库管理员 识别潜在的 SQL 共享问题

    FORCE_MATCHING_SIGNATURE 的局限性

    尽管  FORCE_MATCHING_SIGNATURE 可以帮助识别相似的 SQL 语句,但它也存在一些局限性:

    无法自动优化执行计划FORCE_MATCHING_SIGNATURE 只能帮助识别相似的 SQL 语句,但它并不能自动优化这些语句的执行计划。数据库管理员仍然需要手动干预,以确保执行计划的稳定性。

  3. 签名计算的复杂性:在某些情况下,SQL 语句的签名可能会因为微小的变化而不同,这可能导致  FORCE_MATCHING_SIGNATURE 无法正确识别相似的 SQL 语句。

  4. 无法解决所有 SQL 共享问题:与  CURSOR_SHARING=FORCE 类似, FORCE_MATCHING_SIGNATURE 也无法解决所有 SQL 共享问题。特别是在处理动态 SQL 或复杂查询时,可能需要其他技术来确保执行计划的稳定性。

    总结

    CURSOR_SHARING=FORCE 和  FORCE_MATCHING_SIGNATURE 是 Oracle 数据库中用于优化 SQL 共享和执行计划稳定性的重要工具。然而,它们在某些情况下存在局限性,尤其是在处理复杂或动态生成的 SQL 语句时。为了确保 SQL 执行计划的稳定性,数据库管理员可能需要结合其他技术(如 SQL 计划基线、SQL 配置文件等)来进行综合优化。

相关推荐