空コミットとは、あるトランザクションでDMLの実行は無いがコミットする、ことを指す。一般的に通用する用語かどうかは謎だが、ひとまずこのエントリ内ではそういうもんとして話を進める。
Oracleでコレがどういう時に現れるかというと、たとえばFOR UPDATE句を多用するシステムが考えられる。トランザクションの終わりで必ずコミットさせるようにして、ロックの解放漏れを防ぐのが目的である。
何もコミットするものがなければREDOログは発生しないハズなので、空コミットの負荷はほとんど無いと考えられる。が、実際どんなもんなのかをやってみるのが、このエントリの趣旨である。
3種類のPL/SQLを用意し、それぞれの実行時間を計測する。3種類とは、SELECTのみ・COMIITのみ・SELECT + COMMITで、それぞれを100万回実行する。
下記は、SELECT + COMMITの100万回ループのパターン。SELECTのみ・COMIITのみは、下記コード中にあるとおり対象行をコメントアウトする。
下記コードのSELECTは、クエリの実行はするがなるべくOracleに負荷をかけないもの、としてこのようなクエリにした。
createor replacePROCEDURE BLANK_COMMITAS INTO_1 INT;BEGINFOR IIN1..1000000LOOPSELECT1INTO INTO_1FROM DUAL;--COMMITのみのとき、この行をコメントアウトするCOMMIT;--SELECTのみのとき、この行をコメントアウトするENDLOOP;END BLANK_COMMIT;
また、計測用プログラム実行前に、下記のようにして手動ログスイッチ&バッファキャッシュのクリアをしている。
ALTER SYSTEM SWITCH LOGFILE;ALTER SYSTEM FLUSH BUFFER_CACHE;
| 種類 | 1 | 2 | 3 |
|---|---|---|---|
| select | 39.125 | 39.000 | 39.031 |
| commit | 26.328 | 26.312 | 26.344 |
| select + commit | 66.765 | 66.844 | 66.781 |
おおむね空コミットの負荷はきわめて小さい、と考えられる。
この環境では、100万回の空コミットにつき約26秒かかっている。大雑把に言えば、100万回のトランザクションにつき空コミットをしない場合に比べれば約26秒損している、と言える。1トランザクションあたりでは0.000026秒の損なので、これはまぁほとんど無いと見なしても良いんではなかろうか。
コミットはしてもREDOログが無ければ、コミットの負荷はほぼCPUの性能依存となると思われる。ウチのOracleマシンはかなりショボイので、より性能の良いマシンであればこの差はもっと小さくなるハズである。この点からも、空コミットの負荷はほとんど無いんじゃないかなぁ、と推測される。
つづき⇒Oracleの空コミットは別セッションのトランザクションに影響を与えるか - kagamihogeの日記
「Oracleの空コミット負荷は気にしなくても良い」をどこで読んだ知識なのか発見した。
COLUMN:空コミットはしないほうが良いですよね?
Oracleは、いわゆる空コミットやSELECTFOR UPDATE以外の問い合わせのみ実行していた場合には、読み取り専用トランザクションの扱いとなり、REDOログファイルに対して書き込みを待機する実際のコミット処理は行ないません。そのため、空コミットが増えることはデータベース全体に対する懸念材料にはなりません。user commits統計値にも反映されません。
門外不出のOracle現場ワザ 第5章
statspackレポート取得して比較しようと思ったけど、めんどくなってやめてしまった。
https://github.com/kagamihoge/oraclestudy/blob/master/plsql/blankcommit/BLANK_COMMIT.sql
https://github.com/kagamihoge/oraclestudy/tree/master/statspackrepots/blankcommit
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。