今天介紹一箇舊版本中固定執行計劃的方法:Outline。
這個方法雖然比較老,可是由於沒有版本限制,SE也可使用,因此還在必定的場景中是能用到的。sql
下面是詳細的步驟和測試結果:oracle
1.TEST用Table作成。ide
create table tab1(c1 number, c2 number, c3 varchar2(10)); declare a number; begin a := 1; for i in 1 .. 50 loop for j in 1 .. 100 loop insert into tab1 values(a,j,'a'); commit; a := a+1; end loop; end loop; end; / create index ind1_1 on tab1(c2); exec dbms_stats.gather_table_stats(ownname=>'TEST',tabname=>'TAB1',cascade=>TRUE);
2.作成兩個Outline。oop
CREATE OUTLINE test_oln_tab1 for category test_oln ON select count(*) from tab1 where c2=1; CREATE OUTLINE test_oln_tab2 for category test_oln ON select /*+ FULL( tab1 ) */ count(*) from tab1 where c2=1;
3.查看一下作成的Outline。測試
SQL> select * from OUTLN.OL$; OL_NAME SQL_TEXT TEXTLEN SIGNATURE HASH_VALUE HASH_VALUE2 CATEGORY VERSION CREATOR TIMESTAMP FLAGS HINTCOUNT SPARE1 SPARE2 TEST_OLN_TAB1 select count(*) from tab1 where c2=1 36 DFCF0A3CF8B2F9EF5D90A595EF5F2B16 1484405676 2172588166 TEST_OLN 19.0.0.0.0 TEST 2/22/2021 15:25 0 6 TEST_OLN_TAB2 select /*+ FULL( tab1 ) */ count(*) from tab1 where c2=1 56 FC573ABD6E39A44C51808D67718F873C 2518267384 3225357337 TEST_OLN 19.0.0.0.0 TEST 2/22/2021 15:25 0 6 SQL> select * from OUTLN.OL$HINTS; OL_NAME HINT# CATEGORY HINT_TYPE HINT_TEXT STAGE# NODE# TABLE_NAME TABLE_TIN TABLE_POS REF_ID USER_TABLE_NAME COST CARDINALITY BYTES HINT_TEXTOFF HINT_TEXTLEN TEST_OLN_TAB1 1 TEST_OLN 1001 INDEX(@"SEL$1" "TAB1"@"SEL$1" ("TAB1"."C2")) 1 1 TAB1 1 1 0 TEST.TAB1 1.000607 50 150 22 4 TEST_OLN_TAB1 2 TEST_OLN 1011 OUTLINE_LEAF(@"SEL$1") 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB1 3 TEST_OLN 1013 ALL_ROWS 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB1 4 TEST_OLN 54 DB_VERSION('19.1.0') 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB1 5 TEST_OLN 1009 OPTIMIZER_FEATURES_ENABLE('19.1.0') 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB1 6 TEST_OLN 1008 IGNORE_OPTIM_EMBEDDED_HINTS 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 1 TEST_OLN 2 FULL(@"SEL$1" "TAB1"@"SEL$1") 1 1 TAB1 1 1 0 TEST.TAB1 5.04028051 50 150 42 4 TEST_OLN_TAB2 2 TEST_OLN 1011 OUTLINE_LEAF(@"SEL$1") 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 3 TEST_OLN 1013 ALL_ROWS 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 4 TEST_OLN 54 DB_VERSION('19.1.0') 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 5 TEST_OLN 1009 OPTIMIZER_FEATURES_ENABLE('19.1.0') 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 6 TEST_OLN 1008 IGNORE_OPTIM_EMBEDDED_HINTS 1 1 0 0 0 0 0 0 0 0 SQL> select * from OUTLN.OL$NODES; OL_NAME CATEGORY NODE_ID PARENT_ID NODE_TYPE NODE_TEXTLEN NODE_TEXTOFF NODE_NAME TEST_OLN_TAB1 TEST_OLN 1 0 45 36 1 SEL$1 TEST_OLN_TAB2 TEST_OLN 1 0 45 56 1 SEL$1
4.把「TEST_OLN_TAB1」和「TEST_OLN_TAB2」的Hint進行互換,達到把加了Hint「 FULL( tab1 ) 」的執行計劃固定給沒加Hint的SQL文。this
SQL> update OUTLN.OL$HINTS set OL_NAME='TEST_OLN_TAB3' where OL_NAME='TEST_OLN_TAB1'; 6行が更新されました。 SQL> update OUTLN.OL$HINTS set OL_NAME='TEST_OLN_TAB1' where OL_NAME='TEST_OLN_TAB2'; 6行が更新されました。 SQL> update OUTLN.OL$HINTS set OL_NAME='TEST_OLN_TAB2' where OL_NAME='TEST_OLN_TAB3'; 6行が更新されました。 SQL> commit; コミットが完了しました。
5.查看一下移花接木後的Outline。code
SQL> select * from OUTLN.OL$; OL_NAME SQL_TEXT TEXTLEN SIGNATURE HASH_VALUE HASH_VALUE2 CATEGORY VERSION CREATOR TIMESTAM FLAGS HINTCOUNT TEST_OLN_TAB1 select count(*) from tab1 where c2=1 36 DFCF0A3CF8B2F9EF5D90A595EF5F2B16 1484405676 2172588166 TEST_OLN 19.0.0.0.0 TEST 21-02-22 0 6 TEST_OLN_TAB2 select /*+ FULL( tab1 ) */ count(*) from tab1 where c2=1 56 FC573ABD6E39A44C51808D67718F873C 2518267384 3225357337 TEST_OLN 19.0.0.0.0 TEST 21-02-22 0 6 SQL> select * from OUTLN.OL$HINTS; OL_NAME HINT# CATEGORY HINT_TYPE HINT_TEXT STAGE# NODE# TABLE_NAME TABLE_TIN TABLE_POS REF_ID USER_TABLE_NAME COST CARDINALITY BYTES HINT_TEXTOFF HINT_TEXTLEN TEST_OLN_TAB1 1 TEST_OLN 2 FULL(@"SEL$1" "TAB1"@"SEL$1") 1 1 TAB1 1 1 0 TEST.TAB1 5.04028051 50 150 42 4 TEST_OLN_TAB1 2 TEST_OLN 1011 OUTLINE_LEAF(@"SEL$1") 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB1 3 TEST_OLN 1013 ALL_ROWS 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB1 4 TEST_OLN 54 DB_VERSION('19.1.0') 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB1 5 TEST_OLN 1009 OPTIMIZER_FEATURES_ENABLE('19.1.0') 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB1 6 TEST_OLN 1008 IGNORE_OPTIM_EMBEDDED_HINTS 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 1 TEST_OLN 1001 INDEX(@"SEL$1" "TAB1"@"SEL$1" ("TAB1"."C2")) 1 1 TAB1 1 1 0 TEST.TAB1 1.000607 50 150 22 4 TEST_OLN_TAB2 2 TEST_OLN 1011 OUTLINE_LEAF(@"SEL$1") 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 3 TEST_OLN 1013 ALL_ROWS 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 4 TEST_OLN 54 DB_VERSION('19.1.0') 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 5 TEST_OLN 1009 OPTIMIZER_FEATURES_ENABLE('19.1.0') 1 1 0 0 0 0 0 0 0 0 TEST_OLN_TAB2 6 TEST_OLN 1008 IGNORE_OPTIM_EMBEDDED_HINTS 1 1 0 0 0 0 0 0 0 0 SQL> select * from OUTLN.OL$NODES; OL_NAME CATEGORY NODE_ID PARENT_ID NODE_TYPE NODE_TEXTLEN NODE_TEXTOFF NODE_NAME TEST_OLN_TAB1 TEST_OLN 1 0 45 36 1 SEL$1 TEST_OLN_TAB2 TEST_OLN 1 0 45 56 1 SEL$1
6.看看Outline能不能固定執行計劃。orm
[oracle@db1903 ~]$ sqlplus test/test@localhost:1521/pdb SQL> set autot on SQL> set lin 120 pages 999 SQL> ALTER SESSION SET USE_STORED_OUTLINES = TEST_OLN; セッションが変更されました。 SQL> select count(*) from tab1 where c2=1; COUNT(*) ---------- 50 実行計畫 ---------------------------------------------------------- Plan hash value: 1117438016 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 3 | 5 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 3 | | | |* 2 | TABLE ACCESS FULL| TAB1 | 50 | 150 | 5 (0)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("C2"=1) Note ----- - outline "TEST_OLN_TAB1" used for this statement 統計 ---------------------------------------------------------- 3 recursive calls 25 db block gets 3 consistent gets 0 physical reads 868 redo size 573 bytes sent via SQL*Net to client 398 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
OK!ip
Summury:
方法雖然好用,可是涉及了手動修改內部表數據,不在ORACLE技術支持的範圍,須要自負責任。get