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

