読者からの質問に関する検証

~読者からの「質mon」に関する検証~
ペンネーム ちゃむ

読者からの質問

前回の Vol32で、1.パフォーマンスの向上(リカーシブ コールの減少 ビッ
トマップを用いた高速なエクステントのアルゴリズム)と有りましたが、リカ
ーシブ コールとは、システム表領域へのアクセスのことを指しているのでしょうか。

今回は上記のような質問(質mon)が多かったのでそれに関して検証を交えて説明
しようと思う。

————————————————————————–
8iからの新機能ローカルエクステントマネージメントを以下「LOCAL」と呼ぶ。
従来のデータディクショナリでエクステントを管理する方法を以下「DICTIONARY」
と呼ぶ。
————————————————————————–

検証する前準備として、「LOCAL」と「DICTIONARY」でそれぞれにテーブルを作成
しておく。

「LOCAL」

/*テーブルスペース作成*/
create tablespace TESTl
datafile 'd:testl' size 10m
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 4k;

/* where 1=2
 にして行数0のテーブル作成  t10man_orgはempの行数を拡張し
た10万件のテーブル*/
create table testl_tb tablespace testl
storage (initial 4k next 4k pctincrease 0 maxextents unlimited)
as select * from t10man_org where 1=2;

「DICTIONARY」

/*テーブルスペース作成*/
create tablespace TESTd
datafile 'd:testd' size 10m
minimum extent 4k;

/* where 1=2 にして行数0のテーブル作成  t10man_orgはempの行数を拡張し
た10万件のテーブル*/

create table testd_tb tablespace testd
storage (initial 4k next 4k pctincrease 0 maxextents unlimited)
as select * from t10man_org where 1=2;

リカーシブコールを正確に把握するために今回はSQL_TRACEを取得することにする。
以下の初期化パラメータを変更する必要があるが、今回はセッションレベルで変更する。
その後10万件のテーブルをインサートする。

「LOCAL」

/*『時間に関する統計情報が正確に取得できる』を真にセットする。*/
alter session set timed_statistics = true ;

/*SQLトレースをそのセッションで取るための設定*/
alter session set sql_trace = true ;

/*10万件のテーブルをインサート*/
insert into testl_tb select * from t10man_org;

初期化パラメータのUSER_DUMP_DESTで指定したディレクトリにOra00245.trcと
いうトレースファイルが出力された。DOSプロンプトで、TKPROFユーティリティー
を用いて、読みやすく整形しよう。

C:> tkprof Ora00245.trc testl_tb.txt

ファイルの更新日時を見れば、今出力されたトレースファイルがOra00245.trcで
あるとわかる。ではこの245という番号はなんであろうか。実はそれは、プロセス
番号である。もし、事前に出力するトレースファイル名を判断する必要があるなら
ば、以下のSQL文で自分の接続しているプロセス番号を把握できる。

select s.server SERVER, p.spid SPID
 from v$session s ,v$process p
 where s.audsid=userenv('sessionid') and s.paddr=p.addr;

SERVER       SPID
-----------------
DEDICATED    245

このプロセス番号を用いてファイル名は一意に決まるが、過去に同じプロセス
番号のトレースファイルもあるかもしれないので、USER_DUMP_DESTにある不要な
ファイルは削除しておくか明示的に上記のSQL文で自分のセッションのプロセス
番号を把握しておくべきであろう。(NT版だと3桁のようなのでバッティングする
ことも時々ある。バッティングした場合トレースファイルにダンプの内容がAPPEND
される。)

ここで、V$SESSIONのSERVER列は以下の内容を示す。

SHAREDまたはNONE → 共有サーバ接続
DEDICATE → 専用サーバ接続

もし、共有サーバ接続でトレースファイルを出力すると、トレースファイルは
以下のような名前になる。

orclS000.TRC

これは、共用サーバのプロセスIDを示すようだ。これでは、トレースファイ
ルは共用サーバの個数によって名前が決まってしまうので、一意性は薄い。
だから、専用サーバ接続でトレースファイルを取ったほうが良い場合もあるだ
ろう。

話を元に戻して、「LOCAL」のトレースファイルを整形したtestl_tb.txtのリカ
ーシブコールのTOTALを見ると以下のとおり。後程、「DICTIONARY」と比較して
みよう。

-----------------testl_tb.txtのTOTAL RECURSIVE CALL抜粋-------------------

OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse     2524      5.04       7.07          3         36          2           0
Execute   2560      1.53       1.72          0       4996       1249        1249
Fetch     2631      0.26       0.44         14       3931          0        1346
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total     7715      6.83       9.23         17       8963       1251        2595

-----------------testl_tb.txtのTOTAL RECURSIVE CALL抜粋-------------------

「DICTIONARY」

alter session set timed_statistics=true;

alter session set sql_trace=true;

insert into testd_tb select * from t10man_org;

/*トレースファイルはOra00241.trcに出力された*/

C:> tkprof Ora00241.trc testd_tb.txt
---------------testd_tb.txtのTOTAL RECURSIVE CALL抜粋------------------

OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse     3692      8.00      11.70          3         36          2           0
Execute   3761      4.32       4.53         19      31688       1914        1832
Fetch    53050      8.39       9.85         42      76243          0       52064
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    60503     20.71      26.08         64     107967       1916       53896

------------------------------------------------------------------------

「LOCAL」と「DICTIONARY」を比較してみよう。リカーシブの実行回数などが、
ぜんぜん違うのは見てわかるだろう。

それぞれの項目の内容を以下に記述する。(トレースファイルから抜粋)

*****************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing 
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call
*****************************************************************************

具体的なリカーシブコールの例をトレースファイルから抜粋してみると以下のような
ものがあった。

例1

/*空スペースの管理
10万件インサートしたことにより、空領域のブロック数などを管理しているfet$
表をdeleteする。*/

delete from fet$ 
where
 file#=:1 and block#=:2 and ts#=:3

例2

/*オブジェクトのエクステント管理
10万件インサートしたことにより、エクステントの使用ブロック数などを管理し
ているuet$表に該当オブジェクトのブロック数などをinsertする。*/

insert into uet$ (segfile#,segblock#,ext#,ts#,file#,block#,length)
values
 (:1, :2, :3, :4, :5, :6, :7)

ということで、fet$やuet$などは、システム表領域に入る基礎表なので、リ
カーシブ コールとは、システム表領域へのアクセスのことを指していると言
えます。

実は、メルマガを12月14日(木)、15日(金)に開催されるORACLE OPEN WORLD
(東京ドーム)の出展に向けて今までのメルマガの他に新企画の準備を進めてい
ます。ORACLE OPEN WORLD開催後は、メルマガ読者はさらに増える?と予想される
ので、さらに内容を充実するべく、スタッフ一同がんばっております。
ですので、通常のテーマを設けて検証する企画は、ORACLE OPEN WORLD開催後の最
初の水曜日である12月20日から再開します。それまでの期間は「ORACLE OPEN WOR
LD 特別企画 OOW出展への道」として行ないますのでよろしくお願いします。

次回のメルマガは、OOWにて無料配布する冊子
「とびだせ!! おら!オラ!Oracle -どっぷり検証生活-」の内容を、少しだ
けご紹介する予定です(もったいぶるなって?)。

以上 海岸の猫をいじめるな!! 茅ヶ崎にて

前回の訂正:桑田圭介→桑田佳祐
言い訳 漢字に自信無かったから、yahooで桑田圭介で検索したらサザンに関して
いっぱい検索されるんだもん。