これまで,SQL文の実行プランはRDBMSによって自動生成されることを説明しました。今回からは,その実行プランに注目します。実行プランは自動生成されますので,通常のアプリケーション開発において意識することはほとんどありません。ですが処理性能上の問題が発生したときには,その良しあしを確認する必要があります。実行プランが良いか悪いかを判断するには,「こういうときにはこういうプランが良い」ということを知っていなければなりません。本連載の狙いはまさにそこにあり,テーブルとSQL文を示し,最適と思われる実行プランを解説します。

 まずは,本連載で使用するテーブルを説明しましょう。連載では,顧客情報を管理する[顧客]テーブルを一つだけ使用します(表1)。カラムは,[顧客番号](整数,4ケタ),[顧客名](固定長の文字列),[性別](整数,0=男性,1=女性),[年齢](整数),[地域](固定長の文字列)――の五つあります。レコード数は30で,表2に,30レコード分のデータをすべて示しました。

表1●[顧客]テーブルの定義
表1●[顧客]テーブルの定義

表2●[顧客]テーブルの定義
表2●[顧客]テーブルの定義

複数レコードをひとまとめにしたブロック

 アプリケーションを開発するのであればテーブル定義の情報(表1)があればいいでしょうが,実行プランの良しあしを把握するにはそれでは不十分です。実行プランの良しあしを見極めるには「ディスク・アクセスがどれくらい行われるか」を把握する必要があります。そのためには,データがディスク上にどのように格納されているかを知っておく必要があります。

 なぜなら多くのRDBMSは,1回のディスク・アクセスで要求するデータ・サイズを固定し,その固定したひとかたまりを基に,ディスク上にデータを格納しているからです。そのひとかたまりを「ブロック」と呼びます(「ページ」と呼ぶこともあります)。ブロック・サイズは8Kバイトや4Kバイトであることが多いです。ここでは説明を簡単にするために,1ブロックに3レコード含まれるとします。

 表2に示した[顧客]テーブルの,ディスク上の格納状態を示したものが図1です。一つのブロックに三つのレコードが含まれ,ディスク上にはブロックが整然と並んでいることを確認してください。

図1●ディスクに格納されている様子
図1●ディスクに格納されている様子
ディスクにはブロック単位で格納される。ブロックのサイズは固定で,一つのブロックには,一般に複数のレコードが含まれる

 RDBMSは,ブロック単位で,データをディスクからデータ・バッファに読み込みます。たとえ1レコードを読み込みたいときであっても,そのレコードを含むブロックごと読み込みます。なぜ1レコードずつ読み込まないのでしょうか。

 いくつかの理由が考えられますが,その一つとして,ディスク・アクセスの回数を減らすことが考えられます。実行プランの良しあしはディスク・アクセスで決まると説明しました。ディスク・アクセスに注目する理由はその処理に時間がかかる注1からですが,レコードごとに読み込もうが,ブロックごとに読み込もうが,(全レコードを読み込むなら)ディスク・アクセスのデータ量は同じです。それなのにレコードごと読み込まないのは,ディスク・アクセスの時間が,データ量よりその回数に大きく左右されるからです。データ量の影響を受けないわけではありませんが,データ量より回数に大きく影響を受けます。

 ディスク・アクセスの回数を減らすことが重要なので,そのために複数レコードをまとめて読み込むというわけです。それならば,ブロック・サイズを大きくし,まとめて全部のデータを1回で読み込めばいいではないかと思われるかもしれません。メモリー量が潤沢にあればそうした方法も有効でしょう。ですが,ほとんどのケースでは,読み込むデータ量に比べてメモリー量は十分ではなく,一度に全レコードをデータ・バッファに読み込むことはできません。ブロック・サイズが大き過ぎても,ディスク・アクセスの回数が増える注2ことになります。

 ここでは,レコードを複数まとめたブロック単位でディスクへの読み書きを行う,ということを理解してください。

監修:藤塚 勤也(ふじづか きんや) NTTデータ 基盤システム事業本部 オープンソース開発センタ 技術開発担当 シニアスペシャリスト
沖電気工業,タンデムコンピューターズ(現日本HP)を経て,2003年より株式会社 NTTデータに勤務。現在は,オープンソース・ソフトウエアを活用したエンタープライズ・システム向けの技術開発・技術支援に従事しており,特にシステムの中核であるRDBMSに注力している。「RDBMS解剖学」(翔泳社)を共著