獲得應用程序所執行的SQL語句
2024-07-21 02:33:17
供稿:網友
我們在確定應用程序性能的時候,更多地會關注其中SQL語句的執行情況。通常應用的性能瓶頸會在數據庫這邊,因此數據庫的sql語句是我們優化的重點。
要對sql語句進行優化,首先要知道應用程序執行了哪些SQL語句。下面我介紹三種方法來獲得應用程序所執行的SQL語句。
方法一:假如你采用的數據庫是Oracle的話,那么可以利用oracle本身的10046事件跟蹤SQL語句。步驟如下:
1、首先獲得spid、sid、serial#,machine為你的機器名
SQL> select b.spid,a.sid,a.serial#,a.machine from v$session a,v$PRocess b where a.paddr = b.addr and a.machine='yz';
SPID SID SERIAL# MACHINE
9497 49 3406 yz
2、利用10046事件開始跟蹤
SQL>execute sys.dbms_system.set_ev(49, 3406,10046,1,'');
PL/SQL procedure sUCcessfully completed.
3、這時候你可以運行應用程序,對于web 應用你就可以打開你認為性能比較差頁面。
4、假如你要查看這段時間執行了哪些sql語句,可以執行下面的語句結束跟蹤
SQL>execute sys.dbms_system.set_ev(49,3406,10046,0,'');
PL/SQL procedure successfully completed.
5、SQL trace 工具會收集這個過程中執行的SQL的性能狀態數據,記錄到一個跟蹤文件中.這個跟蹤文件提供了許多有用的信息,例如解析次數.執行次數,CPU使用時間等。
6、這時候你可以通過下面的語句獲得產生的跟蹤文件所在的目錄
SQL> select value from v$parameter where name = 'user_dump_dest';
VALUE
--------------------------------------------------------------------------------
/opt/oracle/admin/ocn/udump
7、在/opt/oracle/admin/ocn/udump下找到yzoracle_ora_9497.trc。9497是你當前應用的spid。
8、注重yzoracle_ora_9497.trc是不可讀的,我們需要執行oracle的tkprof命令,將yzoracle_ora_9497.trc轉化為我們可讀的文本文件。
tkprof yzoracle_ora_9497.trc yzoracle_ora_9497.sql
這樣你就可以在yzoracle_ora_9497.sql文件中看到所有的sql語句執行次數,CPU使用時間等數據。
方法二:采用P6Spy
p6spy是一個開源軟件,它可以跟蹤任何使用JDBC的應用產生的數據庫操作。非凡適合于監控EJB服務器產生的 SQL statements。
官方網址:http://www.p6spy.com/
目前P6Spy 適用的應用服務器包括JBoss, ATG, Orion, JOnAS, iplanet, WebLogic, WebSphere, Resin and Tomcat.
下面我介紹一下p6spy在weblogic上安裝的步驟:
?。?)http://www.p6spy.com/download.Html,下載zip包
?。?)解壓出p6spy.jar spy.properties兩個文件
?。?)將p6spy.jar 和spy.properties所在目錄放入weblogic的classpath
(4)修改spy.properties
realdriver= oracle.jdbc.driver.OracleDriver 數據庫驅動程序的名字
?。?)在weblogic控制臺,修改JDBC-Connection Pool的driver class 類名為com.p6spy.engine.spy.P6SpyDriver
(6)重啟weblogic
?。?)這樣在weblgoic的DOMAIN_HOME目錄下的spy.log記錄了數據庫的訪問情況。
方法三:養成良好的編程習慣。在應用的數據訪問層DAO的程序中,采用log4j打印出數據庫操作的日志,這樣你就可以在log中看到執行的sql語句了。
比如:
public List getContactList(String loginId) throws ImContactDAOException {
try {
conn = getDataSource().getConnection();
sql = "select a.login_id, a.contact_id,from im_contact a where a.login_id = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, loginId);
rs = stmt.executeQuery();
log.debug("SQL: " + sql);;
......
} catch (SQLException se) {
....
} finally {
....
}
}
假如你采用hibernate實現O/R Mapping的話,只需要在hibernate.cfg.xml文件中修改show_sql為true,hibernate就會打印出sql的語句。
<property name="show_sql">true</property>
很顯然,三種方法各有自己的優點和適用場合。
方法一,適合于oracle數據庫,獲得的信息豐富,不僅有sql語句,而且包括了各條sql語句執行的情況,非常方便我們調優。
方法二和方法三都會打印出執行的sql語句,它與數據庫平臺無關,不過不能得到相關的sql性能數據。對于方法三,假如我們系統不是采用jdbc進行數據庫操作的話,比如EJB的Entity Bean,日志中就不會打印出相應的sql操作。不過EJB的Entity Bean目前已經被認為是失敗之舉,你可以在項目的重構中可以把這塊重構掉,這個體外話了。
大家可以根據自己項目的情況,選擇合適的方法來跟蹤應用產生的SQL操作。