SQL优化篇--绑定执行计划(手工制造正确执行计划)

生产数据库中经常出现SQL语句走错执行计划的情况,如果该sqlid还有其他高效的执行计划,可以通过coe_xfr_sql_profile.sql脚本进行绑定,但是如果sqlid没有高效的执行计划,就需要通过自己手工生成一个执行计划(通过加hint,或者其他方法),然后将手工生成的 执行计划绑定到生产中运行的sqlid上,下面就演示下具体方法:
–下面SQL正常走ob.object_id列上的索引IDX1_OB
select ob.owner,ob.object_name from ob,tt where ob.object_id = tt.object_id and tt.name = ‘a255’;

通过baseline绑定到下面SQL语句的执行计划上
select /+full(ob)/ ob.owner,ob.object_name from ob,tt where /fengsongtao/ ob.object_id = tt.object_id and tt.name = ‘a255’;

1、查看当前sql的SQL_ID和PLAN_HASH_VALUE
select sql_id,plan_hash_value,sql_text,parse_calls,executions from v$sql where sql_text like ‘select ob.owner,ob.object_name from ob,tt where ob.object_id = tt.object_id and%’;

SQL_ID: cw9ykcy4nxagr
PLAN_HASH_VALUE: 4294070672

2、根据上面的SQL_ID和PLAN_HASH_VALUE生成SQL_HANDLE
–创建baseline
declare
l_pls number;
begin
l_pls := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id => ‘cw9ykcy4nxagr’,
plan_hash_value => 4294070672,
enabled => ‘NO’); --注意这里是no
end;
/
–查看生成的baseline
select sql_handle,
plan_name,
origin,
enabled,
accepted,
fixed,
creator,
optimizer_cost,
sql_text
from dba_sql_plan_baselines
where origin = ‘MANUAL-LOAD’
order by created desc;

SQL_HANDLE: SQL_e869f85cdf464308
PLAN_NAME: SQL_PLAN_fhugsbmgnchs8ee1114be

3、手工生成需要的执行计划
–多次执行下面sql
select /+full(ob)/ ob.owner,ob.object_name from ob,tt where /fengsongtao/ ob.object_id = tt.object_id and tt.name = ‘a255’;

SQL_ID: 232n5typ7xcmd
PLAN_HASH_VALUE: 1115602488

—将原sql的sql_handle与正确的执行计划(手工生成的sql_id和plan_hash_value)做关联
declare
l_pls number;
begin
l_pls := DBMS_SPM.load_plans_from_cursor_cache(sql_id => ‘232n5typ7xcmd’, – new sql_id
plan_hash_value => 1115602488, --new plan_hash_value
sql_handle => ‘SQL_e869f85cdf464308’ --原sql的sql_handle
);
end;
/

4、删除原来的的执行计划
–查看原sql对应的sql_handle有两个执行计划(plan_name)
select sql_handle, plan_name, origin, enabled, accepted,fixed,creator,optimizer_cost,sql_text
from dba_sql_plan_baselines where origin = ‘MANUAL-LOAD’ and sql_handle=‘SQL_e869f85cdf464308’;

SQL_e869f85cdf464308 --> SQL_PLAN_fhugsbmgnchs8ee1114be --原执行计划
SQL_e869f85cdf464308 --> SQL_PLAN_fhugsbmgnchs8b10f07f0 --手工生成的执行计划

–查看两个执行计划的具体内容如下:
select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>‘SQL_e869f85cdf464308’,plan_name=>‘SQL_PLAN_fhugsbmgnchs8ee1114be’));


SQL handle: SQL_e869f85cdf464308
SQL text: select ob.owner,ob.object_name from ob,tt where ob.object_id =
tt.object_id and tt.name = ‘a255’


Plan name: SQL_PLAN_fhugsbmgnchs8ee1114be Plan id: 3994096830
Enabled: NO Fixed: NO Accepted: YES Origin: MANUAL-LOAD

Plan hash value: 4294070672


| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

| 0 | SELECT STATEMENT | | 65988 | 6830K| 33 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 65988 | 6830K| 33 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 65988 | 6830K| 33 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | TT | 1 | 10 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | IDX1_OB | 32 | | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID| OB | 63450 | 5948K| 30 (0)| 00:00:01 |

Predicate Information (identified by operation id):

3 - filter(“TT”.“NAME”=‘a255’)
4 - access(“OB”.“OBJECT_ID”=“TT”.“OBJECT_ID”)

select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>‘SQL_e869f85cdf464308’,plan_name=>‘SQL_PLAN_fhugsbmgnchs8b10f07f0’));


SQL handle: SQL_e869f85cdf464308
SQL text: select ob.owner,ob.object_name from ob,tt where ob.object_id =
tt.object_id and tt.name = ‘a255’


Plan name: SQL_PLAN_fhugsbmgnchs8b10f07f0 Plan id: 2970552304
Enabled: YES Fixed: NO Accepted: YES Origin: MANUAL-LOAD

Plan hash value: 1115602488


| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

| 0 | SELECT STATEMENT | | 65988 | 6830K| 5493 (1)| 00:01:06 |
|* 1 | HASH JOIN | | 65988 | 6830K| 5493 (1)| 00:01:06 |
|* 2 | TABLE ACCESS FULL| TT | 1 | 10 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| OB | 1649K| 151M| 5485 (1)| 00:01:06 |

Predicate Information (identified by operation id):

1 - access(“OB”.“OBJECT_ID”=“TT”.“OBJECT_ID”)
2 - filter(“TT”.“NAME”=‘a255’)

–删除原来的的执行计划
declare
l_pls number;
begin
l_pls := DBMS_SPM.DROP_SQL_PLAN_BASELINE(sql_handle => ‘SQL_e869f85cdf464308’, --sql_handle_for_original
plan_name => ‘SQL_PLAN_fhugsbmgnchs8ee1114be’ --sql_plan_name_for_original
);
end;
/

–再次查看
select sql_handle,
plan_name,
origin,
enabled,
accepted,
fixed,
creator,
optimizer_cost,
sql_text
from dba_sql_plan_baselines
where origin = ‘MANUAL-LOAD’
and sql_handle = ‘SQL_e869f85cdf464308’

你可能感兴趣的:(Oracle)