在Oracle中(在Oracle企业管理器中查看)我有一个特定的SQL Plan Baseline,设置为Enabled = YES。
但是,我无法获得ACCEPTED = YES。根据文档,您需要ENABLED和ACCEPTED两者。
我试图"进化"基线,但OEM(通过报告)抱怨它的情况要差1.06倍。但事实并非如此。
此外,我想知道如何确保它不会随着时间的推移自动清除并且它已被修复。谢谢!
答案 0 :(得分:4)
要启用基线使用, optimizer_use_sql_plan_baselines 必须为true。
SELECT * FROM dba_sql_plan_baselines
考虑具有最低成本或最佳经过时间的计划的基线。优化程序将选择成本最低的计划,但会优先考虑固定计划。这是保证CBO使用计划的最佳方式,尽管有一些计划的提示和SQL配置文件。
使用你的基线加载,然后从dba_sql_plan_baselines视图中获取sql句柄。
尝试使用以下方式进化:
SET LONG 10000
SELECT DBMS_SPM.evolve_sql_plan_baseline(sql_handle => 'SQL_handle_xxxxxx') FROM dual;
var report clob;
exec :report := dbms_spm.evolve_sql_plan_baseline();
print :report
计划的演变只会在更多计划可用时才有效。
有时你需要修复来强制基线,例如:
SET SERVEROUTPUT ON
DECLARE
l_plans_altered PLS_INTEGER;
BEGIN
l_plans_altered := DBMS_SPM.alter_sql_plan_baseline(
sql_handle => 'SQL_handle_xxxxxx',
plan_name => 'SQL_PLAN_xxxxxxx',
attribute_name => 'fixed',
attribute_value => 'YES');
DBMS_OUTPUT.put_line('Plans Altered: ' || l_plans_altered);
END;
/
通常不会立即使用该计划,并且有各种方法可以尝试强制它......
一种方法是杀死运行该语句的所有会话,如果可行的话。
您还可以使用表格使游标无效:
begin
dbms_stats.gather_table_stats(ownname=> '<schema>',
tabname=> '<table>', no_invalidate => FALSE);
end;
使用旧方法进行分析也会使光标无效!
SQL> analyze table <table> estimate statistics sample 1 percent;
检查:
SQL> select child_number, executions, parse_calls, loads, invalidations
from v$sql where sql_id = '<SQLID>';
事件顺序:
- 锁定用户
- 使光标无效
- 终止以该用户身份登录的所有会话
- 解锁用户
- 再次检查
醇>