2014-12-25 Created By 鮑新建
一、摘要
在ORACLE數據庫應用調優中,一個SQL的執行次數/頻率也是常常需要關注的,因為某個SQL執行太頻繁,要麼是由於應用設計有缺陷,需要在業務邏輯上做出優化處理,要麼是業務特殊性所導致。
如果執行頻繁的SQL,往往容易遭遇一些並發性的問題。
那麼如何查看ORACLE數據庫某個SQL的執行頻率/次數,潇湘隱者同學整理如下,借花獻佛了 :)
方法1: 通過查詢V$SQLAREA或V$SQL的EXECUTIONS來查看SQL的執行次數;
方法2:通過DBA_HIST_SQLSTAT關聯DBA_HIST_SNAPSHOT找出某些SQL的執行次數;
方法3:AWR報告查看某個SQL的執行次數;
二、三種方法解析
1. 通過查詢V$SQLAREA或V$SQL的EXECUTIONS來查看SQL的執行次數
(1). 缺點
但是這個值的有效性需要結合FIRST_LOAD_TIME來判斷,因為V$SQLAREA或V$SQL中不保存歷史數據,
具有一定的時效性,所以如果要查詢很久以前的某個SQL執行次數是辦不到的。
(2). 關於V$SQLAREA 欄位介紹
FIRST_LOAD_TIME VARCHAR2(19) Timestamp of the parent creation time
EXECUTIONS NUMBER Total number of executions, totalled over all the child cursors
(3). 如何查詢
SELECT SQL_ID, SQL_TEXT,FIRST_LOAD_TIME, EXECUTIONS FROM V$SQLAREA WHERE SQL_ID = '497wh6n7hu14f'
(4). 總結
如果此時清空共享池,那麼你會發現V$SQLAREA中對應的SQL的EXECUTIONS次數清零了。
如果要查看某個時間段該SQL語句執行了多少次,那麼必須在這兩個時間段執行上面SQL語句,兩次EXECUTIONS的差值表示這段時間內SQL語句的執行次數。
EXECUTIONS是全局的,往往不能查看某個會話或用戶執行了多少次。這也是其局限性之一。
2. 通過DBA_HIST_SQLSTAT關聯DBA_HIST_SNAPSHOT找出某些SQL的執行次數。
(1). 缺點
但是部分快照如果沒有捕獲到有些SQL。這樣也就無法通過下面SQL語句查看執行次數。
也是就說這種方法是有缺陷的。執行越頻繁的語句,也越容易被SNAPSHOT抓取到.
(2). 執行語法
SELECT M.SQL_ID, TO_CHAR (N.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD') "DATETIME", SUM (M.EXECUTIONS_DELTA) EXECUTIONS FROM DBA_HIST_SQLSTAT M, DBA_HIST_SNAPSHOT N WHERE M.SNAP_ID = N.SNAP_ID AND M.DBID = N.DBID AND M.INSTANCE_NUMBER = N.INSTANCE_NUMBER AND M.INSTANCE_NUMBER = 1 AND TO_CHAR (N.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD') = '2014-12-25' AND M.SQL_ID = '497wh6n7hu14f' GROUP BY M.SQL_ID, TO_CHAR (N.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD') ORDER BY M.SQL_ID
3. AWR報告查看某個SQL的執行次數,同上面一樣,AWR報告也受SNAPSHOT影響。不一定捕獲了你需要查詢的SQL
4. 查看當前數據庫執行次數最多的SQL,例如,查詢執行最頻繁的TOP 15的SQL語句。
SELECT SQL_TEXT, EXECUTIONS FROM (SELECT SQL_TEXT, EXECUTIONS, RANK () OVER (ORDER BY EXECUTIONS DESC) EXEC_RANK FROM V$SQLAREA) WHERE EXEC_RANK <= 15;
一、摘要
在做咨詢時,經查遇到以前SQL的運行情況,和查詢使用的條件
查詢綁定變量時,有硬解析和軟解析之分,如果是軟解析,變量的值就很難找到了
查詢綁定變量的幾個視圖如下:
二、查詢v$sql視圖
1. 查詢bind_data
select sql_id, sql_text, bind_data, hash_value
from v$sql
where sql_text like '%select * from test where id1%';
它的記錄頻率受_cursor_bind_capture_interval 隱含參數控制,默認值900,表示每900秒記錄一次綁定值,可以通過alter system set "_cursor_bind_capture_interval"=10;
2. bind_data
select dbms_sqltune.extract_binds(bind_data) bind
from v$sql
where sql_text like '%FROM TEST11%';
此時查詢到的data值得形式是這樣的:BEDA0B2002004F8482D10065FFFF0F000000003132303431313,需要通過dbms_sqltune.extract_binds進行轉換
三、查詢v$sql_bind_capture
通過v$sql_bind_capture視圖,可以查看綁定變量,但是這個視圖不太給力,只能捕獲最後一次記錄的綁定變量值。
而且兩次捕獲的間隔有一個隱含參數控制。默認是900秒,才會重新開始捕獲。在900內,綁定變量值的改變不會反應在這個視圖中。
10G以後可以通過如下方法查看AWR報告裡記錄的SQL的綁定變量值。
select value_string from v$sql_bind_capture where sql_id='abhf6n1xqgrr0';
四、查詢dba_hist_sqlbind
10G以後可以通過如下方法查看AWR報告裡記錄的SQL的綁定變量值。
select snap_id, name, position, value_string,last_captured,WAS_CAPTURED from dba_hist_sqlbind where sql_id = '576c1s91gua19' and snap_id='20433'; ----------snap_id, AWR報告的快照ID。 ----------name, 綁定變量的名稱 ----------position,綁定值在SQL語句中的位置,以1,2,3進行標注 ----------value_string,就是綁定變量值 ----------last_captured,最後捕獲到的時間 ----------was_captured,是否綁定被捕獲,where子句前面的綁定不進行捕獲。
dba_hist_sqlbind視圖強大的地方在於,它記錄了每個AWR報告裡的SQL的綁定變量值,當然這個綁定變量值也是AWR生成的時候從v$sql_bind_capture采樣獲得的。
通過這個視圖,我們能夠獲得比較多的綁定變量值,對於我們排查問題,這些值一般足夠了。
還有一個需要注意的地方是,這兩個視圖中記錄的綁定變量只對where條件後面的綁定進行捕獲,這點需要使用的時候注意。
查詢 dba_hist_sqlbind value_string列
dba_hist_sqlbind是視圖v$sql_bind_capture歷史快照
五、查詢wrh$sqlstat
兩外一個查詢綁定變量的視圖
select dbms_sqltune.extract_bind(bind_data, 1).value_string from wrh$_sqlstat where sql_id = '88dz0k2qvg876'
----------根據綁定變量的多少增加dbms_sqltune.extract_bind(bind_data, 2).value_string等
參考:aaaaaaaa2000 - http://blog.csdn.net/aaaaaaaa2000/article/details/7401110
參考:潇湘隱者 - http://www.cnblogs.com/kerrycode/p/4111746.html (略加排版)