データベースについて調べてみた

データベースについて調べたことのメモ。Oracle要素多めになる予定。

データパッチにおけるUPDATE vs INSERT方式について調べてみた ~ その3 ~

前回は検証方法について記載したため、今回は検証結果について纏めた。

 

1.検証結果まとめ

検証結果は以下の通り。真面目にやるなら複数回実行して平均値を取って比較とかするところだが、面倒なので今回は1発勝負。

検証の結果、Exchange Partition + INSERT方式の方が早いことが確認できた。

  UPDATE INSERT
実行時間[s] 3.49 1.98
CPU時間[s] 3.44 1.93
論理読込ブロック数(query) 10,557 14,640
論理読込ブロック数(current) 512,981 87,300
UNDO生成量[MB] 76.8 25.6

 

100万件(約100MBのテーブル)の簡易な検証だったので、あまり差が出ないかと思っていたが、結構な差を確認することができた。

顕著なのは、論理読込ブロック数(current)の差だ。UPDATE方式の方が多いというより、INSERT方式の方が少ないという表現が正しいだろう。これは、ダイレクトパスインサートを使用していたことで、バッファキャッシュアクセスが回避されたためだと考えられる。

※論理読込ブロック数(current)は、データブロックを更新するために読込んだ回数みたいなイメージ

UNDOの生成量もそれなりの差分が発生していることが確認できたが、感覚的に、UNDOの生成はその時のDBの内部状態で変動する幅が大きい気がするため、1回だけの測定結果であるので、参考程度にとどめておこうと思う。

 

2.UPDATE方式の結果

UPDATE方式のSQLトレースおよびV$TRANSACTIONの結果は以下の通り。

2.1 SQLトレースの結果
UPDATE tab01 SET flg = 1 
WHERE
 flg = 0 and ym = '202302'


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.01          0          0          1           0
Execute      1      3.43       3.49      20791      10557     512980      499196
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      3.44       3.51      20791      10557     512981      499196

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 77  
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         0          0          0  UPDATE  TAB01 (cr=10778 pr=20791 pw=0 time=3505652 us starts=1)
    499196     499196     499196   PARTITION RANGE SINGLE PARTITION: 2 2 (cr=10397 pr=10393 pw=0 time=444443 us starts=1 cost=2862 size=4500000 card=500000)
    499196     499196     499196    TABLE ACCESS FULL TAB01 PARTITION: 2 2 (cr=10397 pr=10393 pw=0 time=391311 us starts=1 cost=2862 size=4500000 card=500000)
2.2 V$TRANSACTIONの結果
        MB
----------
  76.84375

 

3.Exchange Partition + INSERT方式の結果

Exchange Parition + INSERT方式のSQLトレースおよびV$TRANSACTIONの結果は以下の通り。

3.1 SQLトレースの結果
-- Exchange Partition
ALTER TABLE tab01 EXCHANGE PARTITION pt_202302 WITH TABLE tab02 INCLUDING 
  INDEXES WITHOUT VALIDATION

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.02       0.01          1          1          5           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.02       0.02          1          1          5           0


-- INSERT~SELECT
INSERT /*+ APPEND */ INTO tab01 partition(pt_202302) (id, ym, flg, val, memo)
  SELECT id, ym, 1, val, memo FROM tab02

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.01          3         93          0           0
Execute      1      1.93       1.98      10414      14547      87300     1000000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      1.94       1.99      10417      14640      87300     1000000

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 77  
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         0          0          0  LOAD AS SELECT  TAB01 (cr=14723 pr=10414 pw=10409 time=1991750 us starts=1)
   1000000    1000000    1000000   TABLE ACCESS FULL TAB02 (cr=10395 pr=10392 pw=0 time=152728 us starts=1 cost=2862 size=68000000 card=1000000)
3.2 V$TRANSACTIONの結果
        MB
----------
  25.59375

 

4.最後に

感覚的に早いだろうと思っていたExchange Partition+INSERT方式が、実際に速い傾向にあることが確認できた。パッチ対象テーブルに対する業務処理(アクセス)を停止できるシステムであれば、データパッチ時の選択肢として十分取り得ると考えている。

パーティションテーブルでない場合でも、Exchange Partitonの代わりに、テーブルリネームを駆使することで、同様の対応が実施できるだろう。

 

 

次の記事:Oracle19cと21cの初期化パラメータの差分について調べてみた ~その1~

 

前回の記事:データパッチにおけるUPDATE vs INSERT方式について調べてみた ~ その2 ~