図1●データ・ファイルにおけるページとエクステントの関係
図1●データ・ファイルにおけるページとエクステントの関係
[画像のクリックで拡大表示]

 データベースのインデックス*1の作成やパラメータの設定は,システムのパフォーマンスを大きく左右します。加えて,メンテナンスの手間にも影響します。「面倒な設定作業はほとんどツールに任せている」なんていう人もいるかもしれませんが,こうした作業をきちんとやることは実用的なシステムを作るには避けて通れません。では,最適なインデックス作成やパラメータ設定ができるようになるにはどうすればよいのでしょうか。

 Part2では,リレーショナル・データベース管理システム(RDBMS)がデータをディスクに格納するやり方やアクセス方法について解説します。さらに,高速な検索が可能なBツリー・インデックスやハッシュ・インデックスのしくみなどを学んでいきましょう。

データベースには3種類のファイルがある

 最初に,データベースを構成するファイルについて簡単に触れておきましょう。データベースは大きく分けて,「データ・ファイル」「ログ・ファイル」「コントロール・ファイル(ルート・ファイル)」の3種類のファイルで構成されます*2

 データ・ファイルは,レコードやインデックスなどのデータを実際に格納するファイルで,データベースの実体とも言えるファイルです。巨大なデータベースの場合には非常に大きなファイルになりますから,必要に応じて複数のデータ・ファイルを作成することもあります。

 ログ・ファイルは,データの追加,更新,削除といった,データベースに対してユーザーやアプリケーションが実行したすべての操作を記録するファイルです。システムがダウンするなどの障害が発生しても,このファイルの情報を利用すればデータベースの内容を復元できます。コントロール・ファイルは,RDBMSが管理するファイルの基本情報を保持しています。容量は小さいですが,非常に重要なファイルなので2重化することもよくあります。

 データ・ファイルについて,もう少し詳しく見てみましょう。データ・ファイルに格納するデータは,大きく分けてシステム用とそれ以外に区別されます。システム用データには,データベースにログインできるユーザーの情報,テーブル,ビュー,インデックスを管理するための情報,オプティマイザが最適化を行うための統計情報などがあります。

 システム以外のデータとしては,テーブルやインデックスの内容,トランザクション*3処理で必要になるデータ,ソート(並べ替え)などを行う際に一時的に作成するデータなどがあげられます。これらのデータは,物理的には複数のファイルにまたがって格納されることもあります。RDBMSは,システム用データとして格納した管理情報に基づいて,物理ファイル内でのテーブルの位置などを決定し,アクセスを行います。

データ・ファイルはページが基本単位

 RDBMSは,データ・ファイル内部の領域を,「ページ」と「エクステント」という二つの単位で管理します。ページはRDBMSがディスク領域を管理する際に基本となる単位で,エクステントはディスク上で連続した複数のページで構成します(図1[拡大表示])。

 ページには,テーブルを構成するレコードや,インデックスのエントリ*4を複数格納します。RDBMSはメモリーとディスクの間の入出力をページ単位で管理し,キャッシュ・バッファ*5への入出力もページごとに行います。

 ページのサイズはRDBMSやOSの種類などによって異なりますが,一般的には数KB程度*6です。Microsoft SQL Server(以下,SQL Server)は8KB固定です。Oracleでは,データベースを作成する際にページ・サイズを設定できます。

 ページ・サイズの決定は,RDBMSのパフォーマンスに影響を与えます。扱うデータやアクセスの特性に合わせて決める必要があります。例えば,1回の入出力で扱う平均的なデータ量が少ない場合には,ページ・サイズが小さいほうが有利です。レコードを一つだけ読み込めばいいような場合でも,ページ全体を読み込むことになり無駄が多くなるからです。一方,1回の入出力で扱うデータ量が多い場合は,ページ・サイズを大きくしたほうが良いでしょう。ページ・サイズが小さいとディスクとの入出力の回数が増えて,効率が悪くなります。

エクステントはオブジェクトに領域を割り当てる単位

 エクステントは,テーブルやインデックスといったデータベースのオブジェクトに対して,領域を割り当てる際の単位です。例えばテーブルを一つ作成すると,RDBMSはそれに対して一つのエクステントを割り当て,その中にレコードを書き込んでいきます。レコードの数が増えてエクステント内のページを使い切ったら,新たなエクステントを追加して割り当てます*7

 テーブルなどのオブジェクトが複数のエクステントで構成される場合,各エクステントは必ずしも連続しているとは限りません。そのため,RDBMSは内部にエクステントを管理する情報を保持しています。テーブルを先頭から順に検索するような場合には,この管理情報に基づいて目的のエクステントを探していきます。

 エクステントのサイズはオブジェクトごとに設定できます。一般的には格納するデータ量に応じてサイズを決定します。エクステント内のページはディスク上で物理的に連続していることが保証されるため,テーブル全体を先頭から検索する際などにはエクステントのサイズを大きくして,テーブルがまたがっているエクステントの数を減らしたほうが高速になります*8

 ただし,むやみに大きなサイズを割り当てると,ディスク領域の無駄づかいになりかねません。小さなオブジェクトに対しても,エクステントのぶんだけの領域を確保してしまうからです。例えば,小さな参照表*9に対してのエクステントは小さくするほうが良いでしょう。

 RDBMSは,テーブルに格納するレコードが増えると自動的にエクステントを割り当てていきますが,レコードが削除されても自動的にエクステントを解放することはありません。レコードを削除するときにページ内のレコードは消去しますが,エクステントが解放可能かどうかまではチェックしないからです。

 したがって,あるテーブルにレコードを追加しようとしたときに「データ・ファイルの領域不足でエクステントを割り当てできない」というようなエラーが発生した場合には,別のテーブルのレコードを削除しても意味がありません。領域を確保するには,別のオブジェクトに割り当てられたエクステント内の情報をすべて消去することによって,エクステントを空き領域として解放する必要があります。

 エクステントには連続したページを割り当てますから,ディスク上の空きページの合計が新しいエクテントに必要なページ数より多くても,ページが連続していない場合には割り当てに失敗することがあります。エクステントのサイズが異なるテーブルの作成や削除を繰り返すと,ファイル内の空き領域が不連続になり,こうしたことが起こりがちです。この場合には,データベースの再編成*10をして空き領域をまとめる必要があります。


加藤 比呂武(かとうひろむ)