测试目的:手工指定索引的方式绑定的执行计划和hint中指定no index,谁的优先级高?
.
固定执行计划-使用SQL Tuning Advisor
固定执行计划-手工指定PLAN OUTLINE
固定执行计划-手工指定索引名称的方式
固定执行计划-使用coe_xfr_sql_profile固定执行计划
固定执行计划-使用SPM(Sql Plan Management)固定执行计划
.
由于上一个测试中,已经绑定了SQL Profile。
这里我们需要先删除该SQL Profile,再手工指定索引的方式绑定执行计划试试看。
确认下SQL PROFILE的内容:
LUNAR@lunardb>select * from dba_sql_profiles; NAME CATEGORY SIGNATURE ------------------------------ ------------------------------ ---------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- CREATED LAST_MODIFIED --------------------------------------------------------------------------- --------------------------------------------------------------------------- DESCRIPTION -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- TYPE STATUS FOR TASK_ID TASK_EXEC_NAME TASK_OBJ_ID TASK_FND_ID TASK_REC_ID ------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ---------------- Lunar_Manaual_sqlprofile DEFAULT 9.9008162990E+18 select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1 12-JAN-16 10.44.30.000000 AM 12-JAN-16 10.44.30.000000 AM MANUAL ENABLED YES Elapsed: 00:00:00.01 LUNAR@lunardb>
删除这个sql profile
LUNAR@lunardb>exec dbms_sqltune.drop_sql_profile('Lunar_Manaual_sqlprofile'); PL/SQL procedure successfully completed. Elapsed: 00:00:00.04 LUNAR@lunardb>select * from dba_sql_profiles; no rows selected Elapsed: 00:00:00.00 LUNAR@lunardb>
通过sqlprof_attr来实现手工指定索引的方式绑定执行计划,执行计划起名为“Lunar_bjgduva68mbqm_profile”:
LUNAR@lunardb>declare 2 v_hints sys.sqlprof_attr; 3 begin 4 v_hints:=sys.sqlprof_attr('INDEX(IDX_LUNARTEST1_N)'); 5 dbms_sqltune.import_sql_profile('select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1', 6 v_hints,'Lunar_bjgduva68mbqm_profile',force_match=>true); 7 end; 8 / PL/SQL procedure successfully completed. Elapsed: 00:00:00.01 LUNAR@lunardb> LUNAR@lunardb>select * from dba_sql_profiles; NAME CATEGORY SIGNATURE ------------------------------ ------------------------------ ---------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- CREATED LAST_MODIFIED --------------------------------------------------------------------------- --------------------------------------------------------------------------- DESCRIPTION -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- TYPE STATUS FOR TASK_ID TASK_EXEC_NAME TASK_OBJ_ID TASK_FND_ID TASK_REC_ID ------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ---------------- Lunar_bjgduva68mbqm_profile DEFAULT 9.9008162990E+18 select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1 12-JAN-16 10.53.46.000000 AM 12-JAN-16 10.53.46.000000 AM MANUAL ENABLED YES Elapsed: 00:00:00.00 LUNAR@lunardb>
查看这个Lunar_bjgduva68mbqm_profile的一些参数,确认是我们指定的索引:
LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint 2 FROM sys.sqlobj$data od, sys.sqlobj$ so, 3 table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h 4 WHERE so.name = 'Lunar_bjgduva68mbqm_profile' 5 AND so.signature = od.signature 6 AND so.category = od.category 7 AND so.obj_type = od.obj_type 8 AND so.plan_id = od.plan_id; HINT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- INDEX(IDX_LUNARTEST1_N) Elapsed: 00:00:00.02 LUNAR@lunardb>
再次执行SQL,看看这个Lunar_bjgduva68mbqm_profile是否生效:
LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1; Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 1172089107 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 4 | 7 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| LUNARTEST1 | 1 | 4 | 7 (0)| 00:00:01 | -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("N"=1) Note ----- - SQL profile "Lunar_bjgduva68mbqm_profile" used for this statement Statistics ---------------------------------------------------------- 7 recursive calls 0 db block gets 28 consistent gets 1 physical reads 0 redo size 519 bytes sent via SQL*Net to client 524 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed LUNAR@lunardb>
结论:
这里看到已经使用了Lunar_bjgduva68mbqm_profile,但是SQL并没有按照Lunar_bjgduva68mbqm_profile中指定的索引名称使用索引。
这里已经使用了我们的SQL PROFILE,但是仍然走全表扫描
说明hint覆盖了手工指定索引的方式绑定的执行计划,说明手工指定索引名称的方式比hint的优先级低。