譯者注: 本文翻譯自Jonathan Lewis的文章Faking Stored Outlines in Oracle 9, 可以從此處下載原文的word版本: Stored Outlines in Oracle 9.
本文與前一篇Oracle 8i/9i中的執行計劃穩定性是Jonathan Lewis先生寫的關于stored outline具體使用以及其中可能涉及到的風險系列文章,也是我所見到的關于stored outline介紹的最詳細的文檔了. 關于stored outline還有以下相關資料可以對照閱讀下:
Oracle Outlines - aka Plan Stability By Kerry Osborne
Plan stability in 10g - using existing cursors to create Stored Outlines and SQL profiles By Randolf Geist
Stored Outlines and Plan Stability By Tim Hall
Tuning Third-party Vendor Oracle Systems :Tuning when you can’t touch the code By Mark Ault
原文為在Oracle 9中偽造存儲概要
在Oracle 9中偽造存儲概要
在前面的文章中,我討論到存儲概要,并且描述了一種通過濫用系統來生成你所需要存儲概要的方法.我同時也指出,在Oracle 9中使用這種方法存在一些風險,因為存儲在數據庫中的細節信息已經變得非常復雜.在接下來的文章中,我將介紹一種合法的操作存儲概要的方法,這種方法可以應用在Oracle 8與Oracle 9中.這篇文章的細節都是基于實驗得出的,實驗環境是Oracle 8.1.7.0與Oracle 9.2.0.1的默認安裝環境.
回顧
當你知道如何通過給一段DML語句添加提示就可以讓它運行的快很多,但是你卻沒有訪問源代碼并將提示放到適當位置的途徑, 你會怎么做?
在上一篇文章中,我展示了你可以如何用存儲概要(也被稱為執行計劃穩定性)來驅使數據庫引擎為你做這種工作.
一個存儲概要由兩個組件組成(寬泛地講)-一個你希望控制的SQL語句,一組每當Oracle發現這條SQL被優化都將在它上面應用的提示.這兩個組件都被保存在一個被稱為outln的數據庫schema中.
我們可以使用一組如圖-1中類似的查詢語句來檢查保存在其中的SQL語句,以及附著在這條SQL語句上的提示.
select name, used, sql_text
from user_outlines
where category = 'DEFAULT'
;
select stage, node, hint
from user_outline_hints
where name = '{one of the names}'
;
Figure 1 Examining stored outlines.
在前面的文章中,我介紹了這樣一種想法來欺騙系統, 使用合法的方法創建一個存儲概要, 接著,使用一個文本相似的但已經添加過提示的語句來創建一個存儲概要,最后,使用一組SQL語句來交換這兩個存儲概要的實際結果來修復存儲概要.
當時,我曾提到這種方法對Oracle 8來講或許是安全的,但是由于在新版本中引入的變化, 在Oracle 9中可能會導致問題.
這篇文章將對這些變化進行考查, 介紹一種合法的方法來得到你想要的一組存儲到outln中的提示,用來解決你的那些問題語句.
相關變化
如果你登錄到outln schema(在Oracle 9中它默認是鎖住的)查看可用的表清單,你將發現Oracle 9比Oracle 8多出來一張表. 這些表為:
ol$ | SQL語句 |
ol$hints | 提示表 |
ol$nodes | 查詢塊 |
第三張表是一張新表,被用來將提示列表與這條SQL語句(一份內部重寫的版本)的多個不同查詢塊.你還將發現,提示列表(ol$hints)也被加強了,其中還包括文本長度與偏移量的細節信息.
圖2為這三張表的詳細描述,用星號標注了Oracle 9中出現的新字段.
ol$
OL_NAME VARCHAR2(30)
SQL_TEXT LONG
TEXTLEN NUMBER
SIGNATURE RAW(16)
HASH_VALUE NUMBER
HASH_VALUE2 NUMBER ***
CATEGORY VARCHAR2(30)
VERSION VARCHAR2(64)
CREATOR VARCHAR2(30)
TIMESTAMP DATE
FLAGS NUMBER
HINTCOUNT NUMBER
SPARE1 NUMBER ***
SPARE2 VARCHAR2(1000) ***
Ol$hints
OL_NAME VARCHAR2(30)
HINT# NUMBER
CATEGORY VARCHAR2(30)
HINT_TYPE NUMBER
HINT_TEXT VARCHAR2(512)
STAGE# NUMBER
NODE# NUMBER
TABLE_NAME VARCHAR2(30)
TABLE_TIN NUMBER
TABLE_POS NUMBER
REF_ID NUMBER ***
USER_TABLE_NAME VARCHAR2(64) ***
COST FLOAT(126) ***
CARDINALITY FLOAT(126) ***
BYTES FLOAT(126) ***
HINT_TEXTOFF NUMBER ***
HINT_TEXTLEN NUMBER ***
JOIN_PRED VARCHAR2(2000) ***
SPARE1 NUMBER ***
SPARE2 NUMBER ***
ol$nodes (completely new in 9)
OL_NAME VARCHAR2(30)
CATEGORY VARCHAR2(30)
NODE_ID NUMBER
PARENT_ID NUMBER
NODE_TYPE NUMBER
NODE_TEXTLEN NUMBER
NODE_TEXTOFF NUMBER
Figure 2 The outln tables.
你可能很快會注意到多處細節-有大量信息被基于這些表的視圖排除在外了.視圖user_outline_hints的視圖定義完全沒有改變,盡管表ol$hints上新增加了10個字段.實際上,這個視圖在Oracle 8的時候就極度不足,因為它遺漏了相當有用的hint#字段.
你還會注意到,Oracle 9現在有兩個hash_value字段.如果你在Oracle 8與Oracle 9中對同樣的SQL語句創建存儲概要,你將發現它們擁有同樣的hash_value,但是Oracle 9中對應的hash_value可能完全不同.
原文轉自:http://blogread.cn/it/article/1030