测试目的: 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