2012-08-01 103 views
2

有一個問題,我必須根據一定的條件更新一個包含數百萬條記錄的表。我寫了一個很長的shell腳本和SQL語句來完成它。爲了檢查性能,我計劃使用說明計劃,從http://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm#19259執行計劃成本估計

這被寫「執行計劃可以不同由於以下內容:」研究它 不同成本 - > 數據量和統計 綁定變量類型 初始化參數 - 在全局或設置會話級別

在這裏我不明白如何初始化參數 - 全局設置或在會話級別設置影響執行計劃。 有人能解釋嗎? 也有任何其他方式我可以檢查解釋計劃或自動跟蹤以外的性能的SQL語句。

回答

1

GLOBAL或會話參數 Oracle是設置了一組初始化參數。如果沒有指定任何內容來覆蓋它們,這些將被默認使用。可以通過使用ALTER SESSION(僅影響單個用戶)或ALTER SYSTEM(影響所有用戶,直到重新啓動Oracle)命令在會話或系統級別更改事件或通過在代碼中使用優化器提示來覆蓋它們。這些可能會影響您看到的計劃。

關於解釋計劃,不同的Oracle數據庫可能有不同的初始化參數或設置了一些會話/系統參數,這可能意味着SAME代碼的行爲不同(通過在一個Oracle數據庫上獲得與另一個Oracle數據庫相比的不同執行計劃數據庫)。

此外,由於執行計劃受所選數據的影響,因此可能在TEST中運行正常的查詢或程序包在數據量更大的PRODUCTION中不會完成。如果代碼沒有使用精確的數據量進行測試(或者如果測試不能像數據一樣保持全部生產量時至少使用從生產數據庫導入的表統計信息),則這是一個常見問題。

示蹤 的建議,到目前爲止,告訴你如何跟蹤單獨聲明假設你知道哪個語句有問題,但你提到你有幾個SQL語句的shell腳本。

如果您使用的是帶有對SQL加上containin這樣幾個SQL語句的單一調用一個在這裏記錄...

#!/bin/ksh 
sqlplus -S user/pass <<EOF 
set heading off 
BEGIN 
     -- DO YOUR FIRST SQL HERE 
     -- DO YOUR SECOND SQL HERE 
END; 
/

EOF 

...你可以創建這樣

一個Oracle跟蹤文件
#!/bin/ksh 
sqlplus -S user/pass <<EOF 
set heading off 
BEGIN 
     ALTER SESSION SET EVENTS '10046 trace name context forever, level 8' 
     -- DO YOUR FIRST SQL HERE 
     -- DO YOUR SECOND SQL HERE 
END; 
/

EOF 
  • 請注意,級別8用於跟蹤WAITS。你可以做4級(綁定變量)和12級(綁定和等待),但我總是發現8級的問題。級別12還可能需要更長的時間才能在全尺寸環境中執行。

現在運行shell腳本做單的執行,然後檢查您的跟蹤文件在SQL創建PLUS使用

SQL> show parameter user_dump_dest 
    /app/oracle/admin/rms/udump 

進入該目錄,如果沒有其他跟蹤已啓用,有將是一個.trc文件,其中包含腳本中整個SQL運行的跟蹤。

您需要使用UNIX命令TKPROF這樣

unix> tkprof your.trc ~/your.prf sys=no sort=fchela,exeela 

將此轉換爲可讀格式現在切換到你的主目錄,並會出現在這些順序列出了SQL語句的.prf文件採取最多的執行時間或獲取時間與解釋計劃一起執行。 tkprof的這組參數使您能夠專注於修復花費時間最長的語句,從而獲得最大的調整回報。

請注意,如果您的shell腳本運行多個sqlplus命令,則每個命令都會創建一個單獨的會話,因此向每個會話添加ALTER SESSION語句將創建單獨的跟蹤文件。

此外,不要忘記,它很容易迷失在細節中,有時調整是關於查看整體圖片,並以另一種方式做同樣的事情,而不是從一個可能獲得幾秒鐘的單一SQL開始,在整體方案中並不有助於減少整體運行時間。

如果可以,儘量減少更新語句的數量,就好像您有一個大表一樣,如果您可以在表中執行一次更新(並且支持更新的索引),那麼效率會更高比做很多小的更新。

也許您可以發佈腳本的相關部分,運行所需的總時間以及需要更多幫助的解釋計劃。

1

就我個人而言,我只信任rowsource操作,因爲這會給出執行時的確切計劃。確實存在一些影響計劃構建的參數。大多數參數將在實例級別上設置,但可以在會話級別上超過。這意味着每個會話都可以擁有自己的一組有效參數。

問題是您需要知道要運行腳本的會話的確切設置。有幾種方法可以更改會話級別設置。可以在登錄觸發器,存儲過程或腳本中更改設置。

如果腳本不受登錄觸發器的影響,並且不會調用任何發出alter session語句的代碼,則將使用您的實例具有的設置。

3

有幾個(初始化)參數會影響語句的執行計劃。立即想到的是OPTIMIZER_MODE

其他不那麼明顯的會話是像NLS設置這樣的事情,可能會影響索引的可用性。

獲得真實執行計劃(除了跟蹤會話和使用tkprof)的另一種方法是將/*+ gather_plan_statistics */提示與'dbms_xplan.display_cursor()'一起使用。

這是通過實際運行使用上述提示第一的語句來完成的(所以這確實需要比「正常」再解釋):

select /*+ gather_plan_statistics */ * 
from some_table 
    join ... 
where ... 

然後該語句完成後,您可以檢索使用計劃使用DBMS_XPLAN:

SELECT * 
FROM table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST');