1. 程式人生 > >Oracle v$SQLAREA

Oracle v$SQLAREA

v$sql與v$sqlarea基本相同,記錄共享sql區(share pool)中sql統計資訊,如記憶體消耗、IO(物流磁碟讀和邏輯記憶體讀)、排序操作、雜湊ID等資料。不同之處在於v$sql為每一條sql保留一個條目,而v$sqlarea中根據sql_text進行group by,統計列進行sum(),通過version_count計運算元指標的個數。

         sql_text相同的sql語句在資料庫中意義可能完全不同,此時,v$sql會有這兩條完全一樣的sql各自的統計資訊,而在v$sqlarea中sql_text相同的2個指標會合並,執行次數,DISK_READS,BUFFER_GETS等統計資訊會累加,這就是v$sqlarea的聚合作用

         v$sqltext中沒有統計資訊,卻儲存著完整的sql語言及其雜湊ID等。

         v$session主要用來確定會話相關資訊,如通過SID和SERIAL來確定一個Session、會話擁有者使用者名稱username、會話狀態、會話由哪個客戶端發起、正在執行什麼sql(通過sql_address、sql_hash_value、sql_id、sql_child_number確定,再借助v$sqltext就可以知道)、鎖等待相關資訊(如所在表、檔案、塊、被鎖行)等。

 

V$SQLAREA 
  本檢視持續跟蹤所有shared pool中的共享cursor,在shared pool中的每一條SQL語句都對應一列。本檢視在分析SQL語句資源使用方面非常重要。 

V$SQLAREA中的資訊列 

HASH_VALUE:SQL語句的Hash值。 
ADDRESS:SQL語句在SGA中的地址。 
這兩列被用於鑑別SQL語句,有時,兩條不同的語句可能hash值相同。這時候,必須連同ADDRESS一同使用來確認SQL語句。 
PARSING_USER_ID:為語句解析第一條CURSOR的使用者 
VERSION_COUNT:語句cursor的數量 
KEPT_VERSIONS: 
SHARABLE_MEMORY:cursor使用的共享記憶體總數 
PERSISTENT_MEMORY:cursor使用的常駐記憶體總數 
RUNTIME_MEMORY:cursor使用的執行時記憶體總數。 
SQL_TEXT:SQL語句的文字(最大隻能儲存該語句的前1000個字元)。 
MODULE,ACTION:使用了DBMS_APPLICATION_INFO時session解析第一條cursor時的資訊 

V$SQLAREA中的其它常用列 

SORTS: 語句的排序數 
CPU_TIME: 語句被解析和執行的CPU時間 
ELAPSED_TIME: 語句被解析和執行的共用時間 
PARSE_CALLS: 語句的解析呼叫(軟、硬)次數 
EXECUTIONS: 語句的執行次數 
INVALIDATIONS: 語句的cursor失效次數 
LOADS: 語句載入(載出)數量 
ROWS_PROCESSED: 語句返回的列總數 

V$SQLAREA中的連線列Column View Joined Column(s) 
HASH_VALUE, ADDRESS V$SESSION SQL_HASH_VALUE, SQL_ADDRESS 
HASH_VALUE, ADDRESS V$SQLTEXT, V$SQL, V$OPEN_CURSOR HASH_VALUE, ADDRESS 
SQL_TEXT V$DB_OBJECT_CACHE NAME 

示例: 
1.檢視消耗資源最多的SQL: 

Sql程式碼 

  1. SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls  
  2. FROM V$SQLAREA  
  3. WHERE buffer_gets > 10000000 OR disk_reads > 1000000  
  4. ORDER BY buffer_gets + 100 * disk_reads DESC;  


2.檢視某條SQL語句的資源消耗: 

Sql程式碼 

  1. SELECT hash_value, buffer_gets, disk_reads, executions, parse_calls  
  2. FROM V$SQLAREA  
  3. WHERE hash_Value = 228801498 AND address = hextoraw('CBD8E4B0');  



查詢前10條效能差的sql語句 

Sql程式碼 

  1. SELECT * FROM (select PARSING_USER_ID,EXECUTIONS,SORTS,COMMAND_TYPE,DISK_READS,sql_text FROM v$sqlarea  
  2. order BY disk_reads DESC )where ROWNUM<10 ;  

說明: 
EXECUTIONS表示同一條SQL語句一共執行了多少次,SORTS表示排序的次數,DISK_READS表示物理讀的數量。 
DISK_READS NUMBER 
The sum of the number of disk reads over all child cursors 

SORTS NUMBER 
Sum of the number of sorts that were done for all the child cursors 

EXECUTIONS NUMBER 
Total number of executions, totalled over all the child cursors 
分析效能差的sql 

Sql程式碼 

  1. SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,   
  2. ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,   
  3. ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,   
  4. SQL_TEXT   
  5. FROM V$SQLAREA   
  6. WHERE EXECUTIONS>0   
  7. AND BUFFER_GETS >0   
  8. AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8  

查詢共享池中已經解析過的SQL語句及其相關資訊 
--EXECUTIONS 所有子游標的執行這條語句次數 
--DISK_READS 所有子游標執行這條語句導致的讀磁碟次數 
--BUFFER_GETS 所有子游標執行這條語句導致的讀記憶體次數 
--Hit_radio 命中率 
--Reads_per_run 每次執行讀寫磁碟數 

籠統的說EXECUTIONS,BUFFER_GETS,Hit_radio越高表示讀記憶體多,磁碟少是比較理想的狀態,因此越高越好 
另外兩個越高讀磁碟次數越多,因此低點好 

選出最佔用資源的查詢 
   

Sql程式碼 

  1. select b.username username,a.disk_reads reads,a.executions exec,  
  2.     a.disk_reads/decode(a.executions,0,1,a.executions) rds_exec_ratio,  
  3.     a.sql_text statement  
  4.     from v$sqlarea a,dba_users b  
  5.     where a.parsing_user_id=b.user_id  
  6.     and a.disk_reads>100000  

 

下面是蓋國強的一篇部落格對v$sqlarea的解釋:

Oracle GV$SQLAREA / V$SQLAREA view Definition,Just record for myself.

This is the definition from Oracle10g 10.2.0.3 :

SELECT inst_id, kglnaobj, kglfnobj, kglobt03,
      kglobhs0 + kglobhs1 + kglobhs2 + kglobhs3 + kglobhs4 + kglobhs5
      + kglobhs6,
      kglobt08 + kglobt11, kglobt10, kglobt01, kglobccc, kglobclc, kglhdlmd,
      kglhdlkc, kglobt04, kglobt05, kglobt48, kglobt35, kglobpc6, kglhdldc,
      SUBSTR (TO_CHAR (kglnatim, 'YYYY-MM-DD/HH24:MI:SS'), 1, 19), kglhdivc,
      kglobt12, kglobt13, kglobwdw, kglobt14, kglobwap, kglobwcc, kglobwcl,
      kglobwui, kglobt42, kglobt43, kglobt15, kglobt02,
      DECODE (kglobt32,
              0, 'NONE',
              1, 'ALL_ROWS',
              2, 'FIRST_ROWS',
              3, 'RULE',
              4, 'CHOOSE',
              'UNKNOWN'
              ),
      kglobtn0, kglobcce, kglobcceh, kglobt17, kglobt18, kglobts4, kglhdkmk,
      kglhdpar, kglnahsh, kglobt46, kglobt30, kglobts0, kglobt19, kglobts1,
      kglobt20, kglobt21, kglobts2, kglobt06, kglobt07,
      DECODE (kglobt28, 0, NULL, kglobt28), kglhdadr,
      DECODE (BITAND (kglobt00, 64), 64, 'Y', 'N'),
      DECODE (kglobsta,
              1, 'VALID',
              2, 'VALID_AUTH_ERROR',
              3, 'VALID_COMPILE_ERROR',
              4, 'VALID_UNAUTH',
              5, 'INVALID_UNAUTH',
              6, 'INVALID'
              ),
      kglobt31, kglobtt0, DECODE (kglobt33, 1, 'Y', 'N'), kglhdclt, kglobts3,
      kglobt44, kglobt45, kglobt47, kglobt49, kglobcla, kglobcbca
  FROM x$kglcursor_child_sqlid
WHERE kglobt02 != 0


The fllowing is the definition from Oracle9iR2 9.2.0.4:

SELECT  inst_id, kglnaobj,
        SUM (  kglobhs0
              + kglobhs1
              + kglobhs2
              + kglobhs3
              + kglobhs4
              + kglobhs5
              + kglobhs6
            ),
        SUM (kglobt08 + kglobt11), SUM (kglobt10), SUM (kglobt01),
        COUNT (*) - 1, SUM (DECODE (kglobhs6, 0, 0, 1)),
        DECODE (SUM (DECODE (kglhdlmd, 0, 0, 1)),
                0, 0,
                SUM (DECODE (kglhdlmd, 0, 0, 1)) - 1
                ),
        SUM (kglhdlkc) / 2, SUM (kglobt04), SUM (kglobt05), SUM (kglobpc6),
        SUM (kglhdldc) - 1,
        SUBSTR (TO_CHAR (kglnatim, 'YYYY-MM-DD/HH24:MI:SS'), 1, 19),
        SUM (kglhdivc), SUM (kglobt12), SUM (kglobt13), SUM (kglobt14),
        SUM (kglobt15), SUM (DECODE (kglobt09, 0, kglobt02, 0)),
        DECODE (COUNT (*) - 1,
                1, DECODE (SUM (DECODE (kglobt09, 0, kglobt32, 0)),
                            0, 'NONE',
                            1, 'ALL_ROWS',
                            2, 'FIRST_ROWS',
                            3, 'RULE',
                            4, 'CHOOSE',
                            'UNKNOWN'
                          ),
                'MULTIPLE CHILDREN PRESENT'
                ),
        SUM (DECODE (kglobt09, 0, kglobt17, 0)),
        SUM (DECODE (kglobt09, 0, kglobt18, 0)),
        DECODE (SUM (DECODE (kglhdkmk, 0, 0, 1)),
                0, 0,
                SUM (DECODE (kglhdkmk, 0, 0, 1)) - 1
                ),
        kglhdpar, kglnahsh, kglobts0, kglobt19, kglobts1, kglobt20,
        SUM (kglobt21), SUM (kglobt06), SUM (kglobt07),
        DECODE (kglobt33, 1, 'Y', 'N'), kglhdclt
    FROM x$kglcursor
GROUP BY inst_id,
        kglnaobj,
        kglhdpar,
        kglnahsh,
        kglnatim,
        kglobts0,
        kglobt19,
        kglobts1,
        kglobt20,
        DECODE (kglobt33, 1, 'Y', 'N'),
        kglhdclt
  HAVING SUM (DECODE (kglobt09, 0, kglobt02, 0)) != 0

下面是對上面的部落格的評論,可以看到oracle對v$sqlarea的效能方面是在不斷改進的。