V$SQL 和V$SQLAREA區別

pxbibm發表於2015-06-05
v$sqlv$sqlarea檢視:

v$sqlareav$sql兩個檢視的不同之處在於,v$sql中為每一條SQL保留一個條目,而v$sqlarea中根據sql_text進行group by,透過version_count計運算元指標的個數。下面對這個問題進行一點延伸探討。

首先介紹一下v$sql檢視,v$sql檢視列舉了共享SQL區(Shared SQL Area)中的SQL統計資訊,這個檢視中的資訊未經分組,每個SQL指標都包含一條獨立的記錄。這個檢視的主要欄位如下:

Column

Datatype

Descrption

SQL_TEXT

VARCHAR2(1000)

當前SQL指標的前1000個字元(也就是說這裡記錄的SQL是不完整的)

EXECUTIONS

NUMBER

執行次數

DISK_READS

NUMBER

這個子指標Disk Read的次數

BUFFER_GETS

NUMBER

這個子指標的Buffer Gets數量

OPTIMIZER_MODE

VARCHAR2(10)

SQL執行的最佳化器模式

OPTIMIZER_COST

NUMBER

SQL執行成本

HASH_VALUE

NUMBER

Library Cache中父指標的Hash Value

 

用前文應用的例子進行進一步說明,假定資料庫中存在一個使用者TQ,使用者下存在一張EMP表(以下測試來自Oracle 10gR2資料庫環境):

tq@NEI> create table emp as select * from scott.emp;
Table created.
tq@NEI> set autotrace on
tq@NEI> select count(*) from emp;
  COUNT(*)
----------
        14
Execution Plan
----------------------------------------------------------
Plan hash value: 2083865914
-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| EMP  |    14 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement
Statistics
----------------------------------------------------------
          5  recursive calls
          0  db block gets
         
7  consistent gets
         
5  physical reads
          0  redo size
        411  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

這個查詢的統計資訊顯示,執行了5個物理讀7Consistent Gets,來看一下v$sql中記錄的統計資料:

sys@NEI> select sql_text,executions,disk_reads,optimizer_mode,buffer_gets,hash_value
  2  from v$sql where sql_text='select count(*) from emp';
SQL_TEXT                       EXECUTIONS DISK_READS OPTIMIZER_ BUFFER_GETS HASH_VALUE
------------------------------ ---------- ---------- ---------- ----------- ----------
select count(*) from emp                1          5 ALL_ROWS             7 2295140356

記錄的資訊和AUTOTRACE顯示的資訊完全一致。在第一次執行時,這個SQLHASH_VALUE被計算出來為2295140356,並且隨之,這個SQL的父指標(Parent Cursor)在記憶體中被建立,一個子指標同時建立父指標可以被認為是Hash Value的相關資訊,子指標可以被認為是SQL的後設資料

再次執行這個查詢,統計資訊中的物理讀(DISK_READS)不再增加,因為資料已經在Buffer中存在,而BUFFER_GETS繼續增加。執行次數也變為2

tq@NEI> select count(*) from emp;
  COUNT(*)
----------
        14
Execution Plan
----------------------------------------------------------
Plan hash value: 2083865914
-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| EMP  |    14 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        411  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed


sys@NEI> select sql_text,executions,disk_reads,optimizer_mode,buffer_gets,hash_value
  2  from v$sql where sql_text='select count(*) from emp';  

                   
SQL_TEXT                       EXECUTIONS DISK_READS OPTIMIZER_ BUFFER_GETS HASH_VALUE
------------------------------ ---------- ---------- ---------- ----------- ----------
select count(*) from emp                2          5 ALL_ROWS            10 2295140356

 

v$sqlarea檢視也是非常重要的一個檢視,在Oracle 9iR2的文件中,Oracle這樣定義這個檢視:v$sqlarea列出了共享SQL區(Shared SQL Area)中的SQL統計資訊,這些SQL按照SQL文字的不同,每條會記錄一行統計資料注意這裡所說的是按照SQL文字來進行區分,也就是說這個檢視的資訊可以看作是根據SQL_TEXT進行的一次彙總統計

v$sqlarea檢視的主要欄位如下:

Column

Datatype

Description

SQL_TEXT

VARCHAR2(1000)

當前指標的前1000個字元

VERSION_COUNT

NUMBER

Cache中這個父指標下存在的子指標的數量

EXECUTIONS

NUMBER

總的執行次數,包含所有子指標執行次數的彙總

DISK_READS

NUMBER

所有子指標的Disk Reads總和

BUFFER_GETS

NUMBER

所有子指標的Buffer Gets總和

OPTIMIZER_MODE

VARCHAR2(10)

SQL執行的最佳化器模

HASH_VALUE

NUMBER

父指標的Hash Value

 

透過前文可以知道,文字相同的SQL語句,在資料庫中的意義可能完全不同。比如資料庫中存在兩個使用者TQDBTAN,兩個使用者各擁有一張資料表EMP

那麼當兩個使用者發出一個查詢select count(*) from emp時,這個查詢訪問的物件,返回的結果可能完全不同,TQ的查詢訪問的是TQ.EMP表,而DBTAN使用者訪問的則是DBTAN.EMP表。但是單從SQL_TEXT上來說,這兩個SQL沒有任何區別。

繼續前面的測試,再來簡單看一下以下的輸出:

dbtan@NEI> create table emp as select * from scott.emp where rownum <9;
Table created.
dbtan@NEI> set autotrace on
dbtan@NEI> select count(*) from emp;
  COUNT(*)
----------
         8
Execution Plan
----------------------------------------------------------
Plan hash value: 2083865914
-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| EMP  |     8 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement
Statistics
----------------------------------------------------------
          5  recursive calls
          0  db block gets
          7  consistent gets
          5  physical reads
          0  redo size
        411  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

現在v$sql中應該有了兩條完全一樣的SQL,但是各自查詢的物理物件卻是截然不同:

sys@NEI> select sql_text,executions,disk_reads,optimizer_mode,buffer_gets,hash_value
  2  from v$sql where sql_text='select count(*) from emp';
SQL_TEXT                       EXECUTIONS DISK_READS OPTIMIZER_ BUFFER_GETS HASH_VALUE
------------------------------ ---------- ---------- ---------- ----------- ----------
select count(*) from emp                3          5 ALL_ROWS            13 2295140356
select count(*) from emp                1          5 ALL_ROWS             7 2295140356

現在再來查詢v$sqlarea檢視,就可以看到這兩個檢視的不同:

sys@NEI> select sql_text,executions,disk_reads,buffer_gets,hash_value,version_count
  2  from v$sqlarea where sql_text='select count(*) from emp';
SQL_TEXT                       EXECUTIONS DISK_READS BUFFER_GETS HASH_VALUE VERSION_COUNT
------------------------------ ---------- ---------- ----------- ---------- -------------
select count(*) from emp                4         10          20 2295140356             2

在這個檢視中,Oraclev$sql中的sql_text相同的2個子指標合併起來,執行次數等資訊也都進行了累計,version_count也顯示為2,這就是v$sqlarea的聚合作用。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12798004/viewspace-1688350/,如需轉載,請註明出處,否則將追究法律責任。

相關文章