許多數據庫"調優人員"從來不問,"是什麼讓這個程序運行了這麼長時間?"相反,他們會參考檢查內容清單,並試圖阻止錯誤發生:
檢查所有Oracle塊請求是否都由數據庫緩存提供服務
檢查是否有全表掃描
檢查所有排序是否都在內存中進行
檢查重做日誌是否與其他所有數據庫文件進行了適當的隔離
等等。
對於某些工作來說,使用檢查內容清單也許很好。但是對於判斷性能問題這樣的工作,試圖確定理論上可能會出錯的每一件事,從而對這個問題進行處理的做法的效率會很低。更有效的方法就是找到這個簡單問題的答案:
是什麼花了這麼長時間?
用於優化Oracle程序的好的策略就如同日常生活中用到的策略。就像這樣:
1. 使用專門的儀器來測定程序的性能,從而監視運行速度慢的程序。
2. 爲運行慢的程序創建資源描述,把程序的響應時間細分爲幾種有用的類型。
3. 通過首先處理響應時間最長的部分來縮短程序的響應時間。
當你瞭解了若干技術細節之後,這個方法就非常簡單了。如果你真的這樣做,那麼每次你都能獲得一個有用的方法,久而久之,你將能在進行性能改進之前預知其結果。
跟蹤
如果你有用於收集程序中每個執行步驟的時間統計信息的高級工具,那就用吧。但只收集彙總數據(如通過對系統全局區[SGA]或其基礎共享存儲段採樣獲得的數據)的工具對於某些類型的問題就不適合。
使用昂貴的監控工具時最常見的彙總錯誤是它們會跨整個Oracle數據庫實例來彙總某一給定時間間隔內資源的使用情況。但是,運行速度慢的程序實際上可能不受資源爭用問題的影響,而這個問題卻完全控制着系統中一些不太重要的程序的性能。
即便是那些在Oracle數據庫會話級上彙總信息的工具在診斷一些重要的問題類型時也存在着缺陷。例如,假設一個程序運行10分鐘,調用了10000次Oracle SQL*Net message from client 這一"等待事件",會話等待該事件的總用時爲8.3分鐘。這意味着會話對SQL*Net message from client事件的等待時間平均爲3秒。但是單從彙總數據看,你無法知道這10000次調用是否每次都用3秒,還是這些調用中也許有一個用了5分鐘,而其餘9999次調用每次只用0.02秒。這兩種情況需要進行完全不同的處理。
在這種情況下最能爲你提供幫助的診斷數據是Oracle的擴展SQL跟蹤數據。擴展SQL跟蹤文件按時間順序顯示了Oracle數據庫內核在指定時間內所完成工作的逐條記錄。收集擴展SQL跟蹤數據幾乎是免費的。最大的花銷是存儲每一個需要引起注意的跟蹤文件所需磁盤空間(很少超過幾兆字節)的費用。
跟蹤自己的代碼。如果能訪問程序的源代碼,則打開其擴展SQL跟蹤就非常容易。首先必須確保會話的TIMED_STATISTICS和MAX_DUMP_ FILE_SIZE參數設置正確:
CODE:
alter session set timed_statistics=true;
alter session set max_dump_file_size=unlimited;
如果沒有設置TIMED_STATISTICS=TRUE,則數據庫內核將把0值而不是真正的持續時間發送到跟蹤文件中。如果對MAX_DUMP_ FILE_SIZE嚴加限制,則會在跟蹤文件中生成下面這樣的消息,而不是你想要的時間數據:
*** DUMP FILE SIZE IS LIMITED TO 1048576 BYTES ***
接下來是激活跟蹤。有幾種方法可以採用。過去的方法是使用ALTER SESSION命令,如下所示:
CODE:
alter session set events '10046 trace name context forever, level 12'
/* code to be traced goes here */
alter session set events '10046 trace name context off'
更好的方法是使用DBMS_SUPPORT包來激活擴展SQL跟蹤:
CODE:
dbms_support.start_trace(waits=>true, binds=>true)
/* code to be traced goes here */
dbms_support.stop_trace()
請注意DBMS_SUPPORT 沒有文檔說明,可能也不是數據庫默認安裝的一部分。要了解DBMS_SUPPORT的信息,請參考MetaLink ( metalink.oracle.com)。
跟蹤別人的代碼。如果你想跟蹤沒有讀/寫權限的代碼,則激活擴展SQL跟蹤就有點麻煩了。但也不會難很多。你首先要獲得你想跟蹤的會話的V$SESSION.SID和V$SESSION.SERIAL#值。然後使用下面的過程調用,可以設置所選會話的TIMED_STATISTICS和MAX_DUMP_FILE_SIZE參數:
CODE:
dbms_system.set_bool_param_in_session(
sid => 42,
serial# => 1215,
parnam => 'timed_statistics',
bval => true)
dbms_system.set_int_param_in_session(
sid => 42,
serial# => 1215,
parnam => 'max_dump_file_size',
intval => 2147483647)
(對於Oracle8 8.1.6以前的版本,你可以用ALTER SYSTEM命令處理這些參數。)
接下來要激活跟蹤。有幾種方法可以採用,包括下面兩個:
方法一是使用DBMS_SUPPORT:
CODE:
dbms_support.start_trace_in_session(
sid => 42,
serial# => 1215,
waits => true,
binds => true)
/* code to be traced executes during this time window */
dbms_support.stop_trace_in_session(
sid => 42,
serial => 1215)
若想激活擴展SQL跟蹤,請不要使用名爲SET_SQL_TRACE_IN_SESSION的DBMS_SUPPORT過程。該過程不允許在跟蹤文件中指定等待和綁定的數據。
第二種方法更爲精緻,但在Oracle數據庫10g之前的版本中並不支持這種方法。 DBMS_MONITOR包的引入解決了許多複雜診斷數據收集問題,這些問題是由連接共享和多線程操作所引起的。你可以在Oracle數據庫10g中指定要跟蹤的服務、模塊或行動,而不指定要跟蹤的Oracle數據庫會話:
CODE:
dbms_monitor.serv_mod_act_trace_enable(
service_name => 'APPS1',
module_name => 'PAYROLL',
action_name => 'PYUGEN',
waits => true,
binds => true,
instance_name => null)
/* code to be traced executes during this time window */
dbms_monitor.serv_mod_act_trace_disable(
service_name => 'APPS1',
module_name => 'PAYROLL',
action_name => 'PYUGEN')
利用DBMS_MONITOR包,Oracle可爲要跟蹤的特定的業務操作提供完全支持激活或停止診斷數據收集的方法。
測試擴展SQL跟蹤。試一試吧。查看第一個跟蹤文件只需使用一個簡單的SQL*Plus會話,就如同下面這樣:
CODE:
alter session set timed_statistics=true;
alter session set max_dump_file_size=unlimited;
alter session set tracefile_identifier='Hello';
/* only in Oracle Database 8.1.7and later */
alter session set events '10046 trace name context forever, level 12'; --前提是該用戶擁有alter session的權限。
select 'Howdy, it is '||sysdate from dual;
exit;
然後在由USER_DUMP_DEST實例參數的值命名的目錄中尋找文件名中包含字符串"Hello"的最新寫入的.trc文件。
SQL> show parameter dump;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
background_core_dump string partial
background_dump_dest string E:\ORACLE\PRODUCT\10.2.0\ADMIN
\PDPMIS\BDUMP
core_dump_dest string E:\ORACLE\PRODUCT\10.2.0\ADMIN
\PDPMIS\CDUMP
max_dump_file_size string UNLIMITED
shadow_core_dump string partial
user_dump_dest string E:\ORACLE\PRODUCT\10.2.0\ADMIN
\PDPMIS\UDUMP
進入E:\ORACLE\PRODUCT\10.2.0\ADMIN\PDPMIS\UDUMP,會看到那個文件。
用你最喜歡的文本編輯器打開它。 閱讀Oracle MetaLink註釋39817.1或(Optimizing Oracle Performance,《優化Oracle性能》)一書,以便大概瞭解原始跟蹤文件中有些什麼。一定要運行跟蹤文件上的tkprof,並研究其輸出,但也不要由於有了tkprof就不再看原始的跟蹤文件。跟蹤文件中還有許多tkprof沒有向你展示的內容。