Wednesday, October 7, 2009

どうしてV$ビューよりX$テーブルのほうが好きなのか。

オラクルの性能問題を扱ってみるとV$ビュー(Dynamic Performance View)を必ず使用するようになります。でも、V$ビューをしばらくの間使用してみると必ずと言ってもいいだけにX$テーブルを使用しようとする欲が生じます。


どうしてそうですか。なぜ暗号のようなまずい顔のX$テーブルが後ではもっと好きになるでしょうか。僕の経験から見ると三つぐらいの理由があるようです。


  1. V$ビューの定義自体をもっとよく分かるように助けてくれる。
  2. 性能面でもっと効率的である。
  3. V$ビューが見せてくれない情報を見せてくれる。

簡単な例で説明してみます。


1. V$ビューの定義自体をもっとよく分かるように助けてくれる。


次はマニュアルで説明しているV$SESSION_WAIT.STATE列の意味です。


V$SESSION_WAIT.STATE VARCHAR2(19) Wait state:
WAITING - Session is currently waiting
WAITED UNKNOWN TIME - Duration of the last wait is unknown; this is the value when the parameter TIMED_STATISTICS is set to false
WAITED SHORT TIME - Last wait was less than a hundredth of a second
WAITED KNOWN TIME - Duration of the last wait is specified in the WAIT_TIME column

何を話しているのかがわかるけど胸に応えないんです。でもV$SESSION_WAITビューの定義を見れば胸によく応えます。

SYS@ukja1021> select view_name, view_definition
2 from v$fixed_view_definition
3 where view_name = upper('&1')
4 ;
old 3: where view_name = upper('&1')
new 3: where view_name = upper('GV$SESSION_WAIT')

select s.inst_id,s.indx,s.ksussseq,e.kslednam, e.ksledp1,s.ksussp1,s.ksussp1r,e.
ksledp2, s.ksussp2,s.ksussp2r,e.ksledp3,s.ksussp3,s.ksussp3r, e.ksledclassid, e.
ksledclass#, e.ksledclass, decode(s.ksusstim,0,0,-1,-1,-2,-2, decode(round(s.k
susstim/10000),0,-1,round(s.ksusstim/10000))), s.ksusewtm,
decode(s.ksusstim, 0, 'WAITING',
-2, 'WAITED UNKNOWN TIME',
-1, 'WAITED SHORT TIME',
decode(round(s.ksusstim/10000),0,'WAITED SHORT TIME','WAITED KNOWN TIME'))
from x$ksusecst s
, x$ksled e where bitand(s.ksspaflg,1)!=0 and bitand(s.ksuseflg,1)!=0 and s.ksus
sseq!=0 and s.ksussopc=e.indx

V$ビューってX$テーブルをベースにするビュ-に過ぎません。従ってビューの定義を見ればまるでアプリのソースコードを見るような効果が得られます。


2. 性能面でもっと効率的である。


バッファヘッダーの情報を表しているV$BHビューとX$BHビューに対する同じSQL文の実行計画を比べてみると次のようです。


UKJA@ukja1021> explain plan for
2 select * from v$bh
3 where file#=:b1 and block#=:b2
4 ;

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 138 | 1 (100)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 1 | 138 | 1 (100)| 00:00:01 |
|* 2 | FIXED TABLE FULL| X$BH | 1 | 108 | 0 (0)| 00:00:01 |
| 3 | FIXED TABLE FULL| X$LE | 100 | 3000 | 0 (0)| 00:00:01 |
--------------------------------------------------------------------------


                                                                           
UKJA@ukja1021> explain plan for
2 select * from sys.x$bh
3 where file#=:b1 and dbablk=:b2
4 ;

-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 533 | 0 (0)| 00:00:01 |
|* 1 | FIXED TABLE FULL| X$BH | 1 | 533 | 0 (0)| 00:00:01 |
-------------------------------------------------------------------------

X$BHテーブルを使用するほうがもっと効率的だというのが分かります。


3. V$ビューが見せてくれない情報を見せてくれる。


一番重要な理由となります。情報は多ければ多いほどいいはずですね。V$ビューはユーザーの便宜性のために一部の情報を隠します。でもこの隠された情報が見たくなる時が多いです。


簡単な例で説明してみます。次のように大量のパースを修行するセッションがあります。


declare
v_cursor number;
begin
for idx in 1 .. 200000 loop
v_cursor := dbms_sql.open_cursor;
dbms_sql.parse(v_cursor, 'select /* cursor_share */ * from t1 where c1 = :b1', dbms_sql.native);
dbms_sql.close_cursor(v_cursor);
end loop;
end;
/

このセッションがどんなLatchを獲得するのかを調べます。V$LATCHHOLDERビューを利用したらいいでしょう。

SYS@ukja1021> desc v$latchholder
Name Null? Type
------------------------------- -------- ----------------------------
1 PID NUMBER
2 SID NUMBER
3 LADDR RAW(4)
4 NAME VARCHAR2(64)
5 GETS NUMBER

V$LATCHHOLDERビューの定義を次のようです。

SYS@ukja1021> @fixed_view GV$LATCHHOLDER
SYS@ukja1021> set long 100000
SYS@ukja1021>
SYS@ukja1021> select view_name, view_definition
2 from v$fixed_view_definition
3 where view_name = upper('&1')
4 ;
old 3: where view_name = upper('&1')
new 3: where view_name = upper('GV$LATCHHOLDER')

VIEW_NAME
------------------------------
VIEW_DEFINITION
--------------------------------------------------------------------------------
GV$LATCHHOLDER
select inst_id,ksuprpid,ksuprsid,ksuprlat,ksuprlnm,ksulagts from x$ksuprlat

ベーステーブルがX$KSUPRLATテーブルでしょう。定義はつぎのようです。

SYS@ukja1021> desc sys.x$ksuprlat
Name Null? Type
------------------------------- -------- ----------------------------
1 ADDR RAW(4)
2 INDX NUMBER
3 INST_ID NUMBER
4 KSUPRPID NUMBER
5 KSUPRSID NUMBER
6 KSUPRLLV NUMBER
7 KSUPRLTY NUMBER
8 KSUPRLAT RAW(4)
9 KSUPRLNM VARCHAR2(64)
10 KSUPRLMD VARCHAR2(64)
11 KSULAWHY NUMBER
12 KSULAWHR NUMBER
13 KSULAGTS NUMBER

V$LATCHHOLDERビューに存在しない多様な情報を提供します。この中でKSULAWHR列はソースコードのどこから呼ばれたのかを意味するしKSULAWHY列は付加的な理由を表します。


過度なパースを修行するセッションについてV$LATCHHOLDERビューを通じて分析した場合とX$KSUPRLATテーブルを通じて分析した場合を比較しましょうか。まずV$LATCHHOLDERビューを利用した場合(prof_latch.sql)は次のようです。


UKJA@ukja1021> @prof_latch 200000 159 %

SID LADDR NAME HITS
---------- -------- ------------------------------ ----------
159 3253DE80 library cache 12037
159 3253E0F0 library cache lock 1595
159 3253DFB8 library cache pin 883

平面的でしょう。 X$KSUPRLATテーブルを利用した場合(prof_latch2.sql)は次のようです。

UKJA@ukja1021> @prof_latch2 200000 159 %

SID LADDR CALLED NAME OBJECT HITS
---- -------- ----------------- ----------------- ----------------- -------
159 3253DFB8 kglpnal: child: a library cache pin 2 1066
lloc space

159 3253DFB8 kglpndl library cache pin 2 402
159 3253E0F0 kgllkal: child: m library cache loc 2 862
ultiinstance k

159 3253E0F0 kgllkdl: child: c library cache loc 2 930
leanup k

159 3253DE80 kglhdgc: child: library cache 2 1176

SID LADDR CALLED NAME OBJECT HITS
---- -------- ----------------- ----------------- ----------------- -------
159 3253DE80 kglhdgn: child: library cache 2 737
159 3253DE80 kgllkdl: child: n library cache 2 2523
o lock handle

159 3253DE80 kglpin: child: he library cache 2 7206
ap processing

159 3253DE80 kglpndl: child: b library cache 2 3293
efore processing

V$LATCHHOLDERビューが隠した情報を利用するのによってずっと立体的な情報が得られます。


X$テーブルに対する情報を得る一番良い方法はV$ビューの定義をV$FIXED_VIEW_DEFINITIONビューを通じて確認してみることです。いくつかのビューを試してみたら以外の良い情報をたくさん得るようになります。より深いレベルに行こうとする方々はぜひ試してみてください。

No comments:

Post a Comment