如何强制接受 SQL 计划基线?
How to force accept a SQL Plan Baseline?
在 Oracle 中(在 Oracle Enterprise Manager 中查看)我有一个特定的 SQL 计划基准,它设置为启用 = 是。
但是,我无法使 ACCEPTED = YES 起作用。根据文档,您需要同时启用和接受。
我尝试 "evolve" 基线,但 OEM 抱怨(通过报告)它差了 1.06 倍。但事实并非如此。
我还想知道如何确保它不会随着时间的推移自动清除,并且已修复。谢谢!
要启用基线使用,optimizer_use_sql_plan_baselines 必须为真。
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;
/
通常不会立即使用计划,有多种方法可以尝试强制执行...
一个是终止所有会话运行 该语句,如果可行的话。
您还可以使用 table 使光标无效:
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>';
事件顺序:
- Lock the user
- Invalidate the cursor
- Kill all sessions logged in as that user
- Unlock the user
- Check again
在 Oracle 中(在 Oracle Enterprise Manager 中查看)我有一个特定的 SQL 计划基准,它设置为启用 = 是。
但是,我无法使 ACCEPTED = YES 起作用。根据文档,您需要同时启用和接受。
我尝试 "evolve" 基线,但 OEM 抱怨(通过报告)它差了 1.06 倍。但事实并非如此。
我还想知道如何确保它不会随着时间的推移自动清除,并且已修复。谢谢!
要启用基线使用,optimizer_use_sql_plan_baselines 必须为真。
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;
/
通常不会立即使用计划,有多种方法可以尝试强制执行...
一个是终止所有会话运行 该语句,如果可行的话。
您还可以使用 table 使光标无效:
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>';
事件顺序:
- Lock the user
- Invalidate the cursor
- Kill all sessions logged in as that user
- Unlock the user
- Check again