SQL Profile生效前提是STATUS='ENABLED'且FORCE_MATCH匹配模式正确:FALSE需SQL文本完全一致,TRUE才按语法结构模糊匹配;须通过DBA_SQL_PROFILES确认状态,并在AWR中用DISPLAY_AWR('ADVANCED')查执行计划Note验证是否实际使用。

查 DBA_SQL_PROFILES 确认 profile 状态和匹配模式
SQL Profile 生效的前提不是“创建成功”,而是 STATUS = 'ENABLED' 且匹配逻辑实际触发。最常被忽略的是 FORCE_MATCH 字段:设为 FALSE(默认)时,SQL 文本必须字面完全一致(包括空格、大小写、绑定变量名),哪怕 AWR 报告里截断了字段名,也会导致不匹配;设为 TRUE 才按语法结构模糊匹配。
执行这个查询确认关键字段:
SELECT name, status, force_match, sql_text FROM dba_sql_profiles WHERE name = 'your_profile_name';
-
STATUS不是ENABLED→ 直接无效 -
FORCE_MATCH = FALSE但 SQL 中有字面量(如WHERE id = 123)→ 只匹配这一条,其他参数值的同构语句全失效 -
SQL_TEXT显示的语句和你实际执行的不一致(比如少了个表别名或多了个 hint)→ 匹配失败
在 AWR 报告中定位目标 SQL 并检查执行计划 Note
AWR 报告本身不直接显示 profile 是否生效,但它的“SQL Statistics”部分能帮你锁定真实执行过的 SQL(SQL_ID),再用 DBMS_XPLAN.DISPLAY_AWR 查它的历史执行计划——只有这里才能看到优化器留下的硬证据。
关键操作分两步:
- 从 AWR 报告的 “SQL ordered by CPU Time” 或 “SQL ordered by Gets” 中找到目标
SQL_ID - 运行:
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('abc123xyz', NULL, NULL, 'ADVANCED'));注意必须加'ADVANCED'参数,否则Note区不会输出 profile 信息
重点找这行:Note: SQL profile "YOUR_PROFILE_NAME" used for this statement。没这行,哪怕 profile 存在且 enabled,也没被这次执行用上。
对比解析阶段 vs 执行阶段:别信 EXPLAIN PLAN
EXPLAIN PLAN FOR 只模拟硬解析路径,不走 runtime binding 和 profile 注入逻辑,结果不可信。真正决定 profile 是否起作用的,是 SQL 实际执行时的硬解析过程——而这个过程只记录在 AWR 的 DBA_HIST_SQLSTAT 和 DBA_HIST_SQL_PLAN 中。
常见误判场景:
- 用
EXPLAIN PLAN看到计划变了,就以为 profile 生效 → 错。可能只是统计信息更新或 bind peeking 导致 - profile 创建后立刻查
V$SQL,发现SQL_PLAN_BASELINE为空 → 正常。V$SQL只反映当前缓存,而 profile 是在硬解析时注入 hints,不生成 baseline - AWR 快照间隔太长(如默认 60 分钟),问题发生后 5 分钟内没快照 → 查不到该时刻的 plan,得手动触发快照:
EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;
RAC 环境下必须跨实例验证
Profile 是全局对象,但生效是 per-instance 的。一个节点上看到 Note,不代表所有节点都用了。尤其当 RAC 各节点负载不均、或某些节点 shared pool 被刷过,会导致 profile 在部分实例上未加载。
查 GV$SQL 比单查 V$SQL 更可靠:
SELECT inst_id, sql_id, sql_profile, plan_hash_value FROM gv$sql WHERE sql_id = 'abc123xyz' AND sql_profile IS NOT NULL;
如果只在一个 inst_id 返回结果,说明 profile 在其他节点没生效——此时要检查各节点的 optimizer_use_sql_profiles 参数是否均为 TRUE,以及是否存在 ORA-13784 类错误被静默忽略。
真正难排查的点在于:profile 生效与否,不取决于你“做了什么”,而取决于 SQL 第一次硬解析时优化器看到的上下文。哪怕参数、统计信息、profile 状态全对,只要那次解析碰上了 bug 或内部 latch 冲突,就可能跳过注入逻辑——所以一定要用 AWR 里的实际执行计划做最终验证,而不是依赖中间状态。


















