📚

Oracleのキャッシュと解析

2023/06/26に公開

Oracleのキャッシュや解析について学習する

こんにちは!わいわわです。
Oracleと基本情報技術者試験の対策を引き続きがんばっています。
今日はキャッシュや解析について学習します。
必須用語であるので、しっかり理解していきます。

キャッシュ

Oracleはディスクに対して読み書きを依頼します。
このOracleは複数のプロセスから構成されていて、同時にSQL文を処理できます。
またプロセスは
・サーバープロセス(SQL文を処理するプロセス)
・バックグラウンドプロセス(主にサーバープロセスを助けるプロセス)
の2つに分かれています。
この部分は前回、取り上げました!
https://zenn.dev/waiwawaiwai/articles/defa860ba20626

ディスクの動作は大変遅く、このディスク処理をできるだけ行わないように
キャッシュと呼ばれる技術が使われています。

キャッシュは最も簡単なチューニング項目であり、よく知られている機能です。
仕事をする際に頻繁に使う道具や本は、机の奥などにしまわれるのではなく、
手の届く位置に置かれるかと思います。

キャッシュのイメージもこのような感じです。
頻繁に使うデータは毎回ディスクから取り出したりせずに
キャッシュと呼ばれるメモリにおいてすぐ使用できるようにしておくのです。

Oracleはこのキャッシュをバッファキャッシュと呼んでおり、
これにヒットするとSQL文処理が高速に行えます。

ブロック

Oracleはブロックという単位でデータを管理します。
I/Oの単位も、バッファキャッシュもブロック単位で管理されています。

ブロックにはブロックヘッダという管理用の領域と空き領域があります。
データが入ればブロックの後ろから順に入っていき、
DELETEで空けば、そこは詰めなおすことはしません。

1つのブロックには複数の行が格納されているため、
1行だけをディスクから読み込むためでも、欲しい行を含むブロックごとキャッシュにおかれます。
なおブロックサイズは選ぶことができます。
データの大容量化やキャッシュの大容量化により最近のシステムでは8KBを採用することが多いです。
大きな表をシーケンシャルアクセスで読み込まなければいけないデータウェアハウスなどでは
16KBや36KBといったサイズが選ばれることもあります。

キャッシュ×インデックス、プロセス

インデックスもブロックからできています。
インデックスが1ブロックに収まらない場合は複数のブロックで構成されます。
普通、複数のブロックが使われ多段の構造になります。

キャッシュはデータがあるブロックごと行われるため、
インデックス内からデータを読み書きする際も非常に活躍するといえます。

また、キャッシュはプロセスごとに持ってしまうと無駄が多いため、
どのOracleからも見ることができるメモリをキャッシュとしています。

他のプロセスのメモリを見ることは
データを壊したりしないようにOSが守っているため原則的にできませんが
共有メモリを使用すると自分のメモリ領域に書いたはずのデータが
即座にほかのプロセスからも見えるようになります。

共有メモリは実際のメモリは1つです。
各プロセスからは自分のメモリのように見えますが、
実際には全プロセスが同じメモリ領域にアクセスしています。

またOracleではこの共有メモリをSGA
共有ではないメモリの一部をPGAと呼んでいます。

必須の機能ではありますがだれでもアクセスできてしまうため、
ロックをかけて排他制御をしないとデータを壊しかねません。
そのため、DBMSでは内部的なロックによりデータを保護しています。
便利ですが、性能トラブルが発生しやすくなっている要因でもあります。

LRUアルゴリズム

バッファキャッシュは頻繁に使うデータのためにあります。
キャッシュに用いられるアルゴリズムとして
LRUアルゴリズムというものが知られています。
簡単に説明すると、最近使われていないデータからキャッシュアウト(捨てていく)するアルゴリズムです。
OracleはこのLRUアルゴリズムに基づくブロックのリストを持っていて、
どのブロックが最近使われていないのかを把握しています。

頻繁に使われないデータをバッファキャッシュにおいておく必要はなく、
具体的には表のフルスキャンのデータは
おいておいてもキャッシュヒットすることが少ないです。
また、フルスキャンのデータを置くことによって頻繁に使われるデータをキャッシュから追い出してしまうことになります。

そのため、Oracleは表と判断すると、
バッファキャッシュにブロックを配置しません。

このような事情から、フルスキャンした際のデータは
バッファキャッシュには載っていないと考えて進めていかなければなりません。

サーバプロセスと解析

サーバプロセスはSQL文の処理を最優先するプロセスです。
Oracleの解析とはSQL文を分解し、
どのような要素(表や列など)から構成されているかと
どのように処理をするのかまで考えることを指します。

Oracleはコストベースというアルゴリズムを持ち、
これは「処理時間やI/O回数が最小になると考えられる処理方法を最上とする」
というアルゴリズムで、これを見積もるためにコストという数値を用います。
このコストは「処理に必要と思われる時間やリソースの使用料」というイメージです。

コストはOracleが自動的に管理してくれていて、
アナライズという作業を通して
・SQL文の情報
・初期化パラメータ
・オプティマイザ統計
などから最適な実行計画を作成し、実行します。

共有プール

解析処理は大変だということと同時に、
CPUリソースも大きく消費するという面もあります。

共有プールは実行計画を再利用し、解析作業を減らすために存在します。
そのため、うまく共有プールを使用することでCPUリソースを節約できるのです

共有プールの特徴として
・最近実行されたSQL文の実行計画がキャッシュされている
・共有メモリにバッファキャッシュと同様に位置する
・中にはディクショナリキャッシュやライブラリキャッシュがある
などの特徴があります。

ディクショナリキャッシュ…統計情報のキャッシュなど
ライブラリキャッシュ…実行計画などのSQL文情報のキャッシュ

先ほど解析について説明しましたが、
先ほど説明したものはハードパースのこと(実行計画を作成する)で、
共有プールにキャッシュされている実行計画が見つかり再利用するケースを
ソフトパースと呼びます。

Statspack

StatspackはOracleのパフォーマンス診断ツールです。
Oracle自体にインストールが可能で、性能情報を収集します。
例えばリソースを大量消費するSQL文を特定したり
キャッシュヒット率を確認することでボトルネックの切り分けが可能です。

実務に入ると様々なツールに触れる機会が増えそうで、楽しみです。

所感

本日はOracleの解析などについて学習しました。
言葉だけの投稿になっていますが、手元にある参考書には
しっかり絵もあり、著作権の関係で載せていませんがより深いところまで理解できています。
データベースはあまり形としてみることができないので、
今のうちにイメージをつけていくことが大事だと思います。
引き続き頑張ります!

Discussion