メモリ容量を大きくするとRDBMSの処理が速くなるのはなぜか?

RDBMSを運用しているシステムのメモリ容量を大きくすると、処理が速くなる場合がありますが、それはなぜでしょうか?
この記事では、その理由についてまとめています。

以前、Linuxにおいてメモリ容量を大きくすると処理が速くなる理由について書きましたが、今回はRDBMSについて書いています。

TL;DR

この記事では、RDBMSを運用しているシステムのメモリ容量を大きくすると、RDBMSの処理が速くなる理由として、以下について説明しています。

  • システムのメモリ容量を大きくすると、バッファプールの容量を大きくすることができる

  • バッファプールの容量を大きくすると、多くのデータをメモリから返却できるようになる

  • 多くのデータをメモリから返却できるようになると、ディスクへのアクセスが減り、RDBMS全体の処理が速くなる

参考

この記事では、WEB+DB PRESS Vol.122 特集3 Rustで実装!作って学ぶRDBMSのしくみを参考にしています。

RDBMSとはなにか?

RDBMSは、RDBの管理システムであり、クエリを受け付けて結果を返却することができます。
では、RDBMSはどのような仕組みで動いているのでしょうか?

RDBMSの仕組み

RDBMSの一般的なアーキテクチャは以下のような層に分かれています。

  • 構文解析器

  • クエリプランナ

  • クエリエクスキュータ

  • アクセスメソッド

  • バッファプールマネージャ

  • ディスクマネージャ

それぞれの役割を説明します。

構文解析器

構文解析器は受け取ったクエリを構文解析して抽象構文木にします。

クエリプランナ

クエリプランナは抽象構文木をもとに実行計画を作ります。
実行計画はアクセスメソッドをどのような順序で、どのようなパラメータで呼び出すかという情報です。
SQLのEXPLAIN文で確認できる実行計画は、クエリプランナが作ったものです。

クエリエクスキュータ

クエリエクスキュータは実行計画通りにアクセスメソッドを呼び出します。

アクセスメソッド

アクセスメソッドはディスク上のデータ構造をたどって、クエリエクスキュータの要求通りの結果を返します。
RDBMSはデータをディスク上に保存しているので、アクセスメソッドはディスク上のデータ構造を取り扱います。
実際のディスクの読み書きはアクセスメソッド自身では行わず、バッファプールマネージャに頼ります。
アクセスメソッドにはアルゴリズムが実装されており、代表的なものとしてB+Treeがあります。

バッファプールマネージャ

バッファプールマネージャはアクセスメソッドの要求に応じてディスク上のデータを貸し出します。
自身では実際のディスクの読み書きをせず、ディスクマネージャに頼ります。

ディスクマネージャ

ディスクマネージャはディスクの読み書きをします。
バッファプールマネージャの要求どおりにデータをディスクから読み出したり書き込んだりします。

ディスクマネージャ

まず、ディスクマネージャの説明をします。
RDBMSはデータを永続化するためにデータをファイルに書き込みます。
ディスクマネージャはファイルの読み書きを担っています。
ディスクマネージャが読み書きするファイルはヒープファイルと呼ばれる構造をしています。

ヒープファイルとページ

ヒープファイルはファイルをページと呼ばれる固定の長さごとに区切ったものです。
ディスクマネージャはヒープファイルからページを読み込んだり、ヒープファイルにページを書き込んだりします。
読み込み元や書き込み先のページはページ番号で指定します。
これらの仕組みはファイルシステムがブロック単位でデバイスを読み書きする仕組みに合わせています。

バッファプールマネージャ

RDBMSはディスクマネージャを直接使わず、外側にバッファプールマネージャを被せて使っています。
バッファプールマネージャを使う理由は、ディスクへのアクセスの遅さを隠蔽するためです。
ディスクへのアクセスはメモリへのアクセスに比べると非常に遅いです。
バッファプールマネージャはページの内容をメモリ上にキャッシュすることでディスクへのアクセスの遅さを隠蔽します。
一度読んだページをメモリに保持しておき、それ以降の読み取りはディスクマネージャにページを要求せずに結果を返却することができます。
これによって、メモリと同程度の速度で結果を返却することができます。

ほとんどのファイルシステムにはファイルの内容をメモリにキャッシュして読み書きを高速化する機能があります。
しかし、RDBMSの多くはファイルシステムだけに頼らず、バッファプールマネージャで独自にキャッシュを管理しています。
それは、RBDMS自身が直接キャッシュを管理したほうが、より賢く管理できるからです。

バッファプールマネージャの仕組み

次にバッファプールマネージャの仕組みを説明します。
RDBMSはバッファプールというページのデータをキャッシュするメモリ上の領域を確保します。
バッファプールには、ページのデータを格納するためのバッファという領域があります。
バッファプールマネージャは必要に応じてページの内容をディスクマネージャから読み込み、バッファに格納します。
どのページのデータがどのバッファに入っているのかという対応関係をページデータというデータ構造で管理します。

バッファプールはメモリ上の領域であり、大きさに限りがあります。
次々にページをバッファプールにキャッシュしていくと、バッファプールはいずれいっぱいになってしまいます。
バッファプールに空きがないと新たなページを読み込むことができないので、バッファを捨ててスペースを確保する必要があります。
バッファプールに割り当てるメモリ容量が大きくなると、より多くのデータをメモリから返却できるようになります。

まとめ

この記事では、RDBMSを運用しているシステムのメモリ容量を大きくすると、RDBMSの処理が速くなる理由として、以下について書きました。

  • システムのメモリ容量を大きくすると、バッファプールの容量を大きくすることができる

  • バッファプールの容量を大きくすると、多くのデータをメモリから返却できるようになる

  • 多くのデータをメモリから返却できるようになると、ディスクへのアクセスが減り、RDBMS全体の処理が速くなる

参考

この記事では、WEB+DB PRESS Vol.122 特集3 Rustで実装!作って学ぶRDBMSのしくみを参考にしました。

次に

PostgreSQLについても書いたので興味があれば読んでみてください。


この記事が気に入ったらサポートをしてみませんか?