测试目的: hint和手工指定OUTLINE参数的方式来帮顶执行计划,谁的优先级高?
.
固定执行计划-使用SQL Tuning Advisor
固定执行计划-手工指定PLAN OUTLINE
固定执行计划-手工指定索引名称的方式
固定执行计划-使用coe_xfr_sql_profile固定执行计划
固定执行计划-使用SPM(Sql Plan Management)固定执行计划
.
由于上一个测试中,已经绑定了sql使用SQL Tuning Advisor中的执行计划,从而使SQL走索引了(覆盖了hint)。这里我们需要先删除该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 ------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ---------------- SYS_SQLPROF_015236655fb80000 DEFAULT 6.5941520220E+17 select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1 12-JAN-16 10.12.39.000000 AM 12-JAN-16 10.12.39.000000 AM MANUAL ENABLED NO 158 EXEC_146 1 1 1 Elapsed: 00:00:00.02 LUNAR@lunardb> 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 = 'SYS_SQLPROF_015236655fb80000' 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 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- COLUMN_STATS("LUNAR"."LUNARTEST1", "N", scale, length=3 distinct=10000 nulls=0 min=1 max=10000) TABLE_STATS("LUNAR"."LUNARTEST1", scale, blocks=20 rows=10000) OPTIMIZER_FEATURES_ENABLE(default) IGNORE_OPTIM_EMBEDDED_HINTS Elapsed: 00:00:00.05 LUNAR@lunardb>
这里我们看到该SQP Profile中提供了详细的表和列的统计信息
并且有“IGNORE_OPTIM_EMBEDDED_HINTS”,也就是忽略嵌入到SQL中的hint
确认一下,当前SQL语句使用了该SQL Profile:
LUNAR@lunardb>select * from table(dbms_xplan.display_cursor('bjgduva68mbqm',null,'outline')); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SQL_ID bjgduva68mbqm, child number 0 ------------------------------------- select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1 Plan hash value: 3241900148 ------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 1 (100)| | |* 1 | INDEX RANGE SCAN| IDX_LUNARTEST1_N | 1 | 3 | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------- Outline Data ------------- /*+ BEGIN_OUTLINE_DATA IGNORE_OPTIM_EMBEDDED_HINTS OPTIMIZER_FEATURES_ENABLE('11.2.0.4') DB_VERSION('11.2.0.4') ALL_ROWS OUTLINE_LEAF(@"SEL$1") INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N")) END_OUTLINE_DATA */ Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("N"=1) Note ----- - SQL profile SYS_SQLPROF_015236655fb80000 used for this statement 37 rows selected. Elapsed: 00:00:00.23 LUNAR@lunardb>
这里我们看到,当前执行确实使用了SQL profile SYS_SQLPROF_015236655fb80000,因此hint no_index失效了
(优先级低于SYS_SQLPROF_015236655fb80000,具体参见固定执行计划-使用SQL Tuning Advisor)
查看SYS_SQLPROF_015236655fb80000的OUTLINE信息:
LUNAR@lunardb>select '''' || extractvalue(value(d), '/hint') || ''',' as outline_hints 2 from xmltable('/*/outline_data/hint' passing ( 3 select xmltype(other_xml) as xmlval 4 from v$sql_plan 5 where sql_id = 'bjgduva68mbqm' and plan_hash_value = '3241900148' and other_xml is not null 6 ) 7 ) d; OUTLINE_HINTS -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 'IGNORE_OPTIM_EMBEDDED_HINTS', 'OPTIMIZER_FEATURES_ENABLE('11.2.0.4')', 'DB_VERSION('11.2.0.4')', 'ALL_ROWS', 'OUTLINE_LEAF(@"SEL$1")', 'INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))', 6 rows selected. Elapsed: 00:00:00.06 LUNAR@lunardb>
这里我们看到该SQP Profile中提供了详细的表和列的统计信息
并且有“IGNORE_OPTIM_EMBEDDED_HINTS”,也就是忽略嵌入到SQL中的hint
现在,我们删除这个SQL Profile,稍后使用上面的OUTLINE手工绑定执行计划:
LUNAR@lunardb>begin 2 DBMS_SQLTUNE.DROP_SQL_PROFILE(name => 'SYS_SQLPROF_015236655fb80000'); 3 end; 4 / PL/SQL procedure successfully completed. Elapsed: 00:00:00.02 LUNAR@lunardb>SELECT * FROM DBA_SQL_PROFILES; no rows selected Elapsed: 00:00:00.00 LUNAR@lunardb>
此时,应该正常按照hint走了全表扫描:
LUNAR@lunardb>set autotrace traceonly exp stat LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1; Elapsed: 00:00:00.03 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) Statistics ---------------------------------------------------------- 114 recursive calls 0 db block gets 137 consistent gets 0 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 15 sorts (memory) 0 sorts (disk) 1 rows processed LUNAR@lunardb>
手工指定sqlprofile参数的方式绑定执行计划:
LUNAR@lunardb>declare 2 v_hints sys.sqlprof_attr; 3 sql_txt clob; 4 begin 5 v_hints:=sys.sqlprof_attr( 6 'BEGIN_OUTLINE_DATA', 7 'IGNORE_OPTIM_EMBEDDED_HINTS', 8 'OPTIMIZER_FEATURES_ENABLE(''11.2.0.4'')', 9 'DB_VERSION(''11.2.0.4'')', 10 'ALL_ROWS', 11 'OUTLINE_LEAF(@"SEL$1")', 12 'INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))', 13 'END_OUTLINE_DATA' 14 ); 15 16 select sql_fulltext into sql_txt from v$sql where sql_id='&sqlid'; 17 dbms_sqltune.import_sql_profile(sql_text => sql_txt, 18 profile => v_hints,name => 'Lunar_Manaual_sqlprofile', 19 replace => TRUE,force_match => TRUE); 20 end; 21 / Enter value for sqlid: bjgduva68mbqm old 16: select sql_fulltext into sql_txt from v$sql where sql_id='&sqlid'; new 16: select sql_fulltext into sql_txt from v$sql where sql_id='bjgduva68mbqm'; PL/SQL procedure successfully completed. Elapsed: 00:00:00.53 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_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.02 LUNAR@lunardb>
再次查询,看看Lunar_Manaual_sqlprofile是否生效:
LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1; Elapsed: 00:00:00.02 Execution Plan ---------------------------------------------------------- Plan hash value: 3241900148 ------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 4 | 1 (0)| 00:00:01 | |* 1 | INDEX RANGE SCAN| IDX_LUNARTEST1_N | 1 | 4 | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("N"=1) Note ----- - SQL profile "Lunar_Manaual_sqlprofile" used for this statement Statistics ---------------------------------------------------------- 34 recursive calls 0 db block gets 13 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 1 sorts (memory) 0 sorts (disk) 1 rows processed LUNAR@lunardb>
这里我们看到Lunar_Manaual_sqlprofile已经生效,且sql语句虽然带有no_index的hint,但是仍然可以按照SQL Profile指定的大纲使用索引
总结:
这里虽然有hint指定了no index,但是sql语句仍然按照Lunar_Manaual_sqlprofile指定的profile使用了index的
说明,使用手工指定outline参数的方式绑定的执行计划优先级高于hint