ビットマップ フィルターを使ったデータ ウェアハウスのクエリ パフォーマンスの最適化

データ ウェアハウスのクエリは、そのほとんどがスター スキーマに従って設計され、数億件の行を 1 回のクエリで処理できます。既定では、スター スキーマに対するクエリがクエリ オプティマイザーによって検出され、効率的なクエリ プランが作成されます。オプティマイザーが効率的なプランを生成するために用いる手法の 1 つにビットマップ フィルターがあります。ビットマップ フィルターは、操作ツリーの特定の部分にあるテーブルから得られた一連の値の圧縮表現を使用して、同じツリーの別の部分にある 2 つ目のテーブルから行を抽出します。このフィルターが実行していることは、基本的には半結合による除去処理です。つまり、2 つ目のテーブルでは、1 つ目のテーブルと結合するのに適した行だけが処理されます。

SQL Server 2008 では、SQL Server 2005 と同様、ビットマップ フィルターは、最適化後のクエリ プランで導入できるほか、クエリ プランの生成中にクエリ オプティマイザーで動的に導入することもできます。フィルターを動的に導入することを最適化されたビットマップ フィルターと呼びます。最適化されたビットマップ フィルターでは、条件に該当しない行をクエリ プランの初期段階でファクト テーブルから排除できるため、スター スキーマを使ったデータ ウェアハウス クエリのパフォーマンスを飛躍的に高めることができます。最適化されたビットマップ フィルターを使用しなかった場合、ディメンション テーブルとの結合操作で条件に該当しない行が削除される前に、操作ツリーのどこかの部分でファクト テーブルのすべての行が処理されてしまいます。最適化されたビットマップ フィルターを適用することによって、条件に該当しない行をファクト テーブルから即座に排除できます。

最適化されたビットマップ フィルターは、SQL Server の Enterprise Edition、Developer Edition、および Evaluation Edition でのみ使用できます。

ビットマップ フィルターについて

ビットマップ フィルターには、ビットマップ インデックスにはない利点があります。ビットマップ インデックスは、値リスト インデックス内の行 ID (RID) リストを表現するための代替形式です。テーブル内の特定の列値を格納している行が、1 つ以上のビット ベクターを使って表されます。どちらも、結果の処理から不要な行を取り除くという点ではきわめて効果的ですが、ビットマップ フィルターとビットマップ インデックスとの間には大きな違いがあります。まず、ビットマップ フィルターはインメモリ構造であるため、基になるテーブルに対して DML (データ操作言語) 操作が実行された場合でもインデックスのメンテナンスに伴うオーバーヘッドを低く抑えることができます。さらに、ビットマップ フィルターは、非常にコンパクトであるという特長があります。既存のディスク格納型のインデックスが、対応するテーブルのサイズに依存するのに対し、ビットマップ フィルターは、クエリの処理時間に与える影響を最小限に抑えながら動的に作成できます。

ビットマップ フィルターと最適化されたビットマップ フィルターの比較

クエリ プランにビットマップ フィルターや最適化されたビットマップ フィルターを実装するには、Bitmap プラン表示操作を使用します。ビットマップ フィルターは、ハッシュ結合またはマージ結合が使用されている並列クエリ プランでのみ適用されます。最適化されたビットマップ フィルターは、ハッシュ結合が使用されている並列クエリ プランにのみ適用できます。いずれの場合も、ハッシュ結合のビルド入力 (ディメンション テーブル) 側にビットマップ フィルターが作成されます。ただし、実際のフィルター処理は、ハッシュ結合のプローブ入力 (ファクト テーブル) 側にある Parallelism 操作内で実行されるのが一般的です。整数型の列に基づく結合の場合、フィルターは Parallelism 操作ではなく、初期テーブルまたはインデックス スキャン操作に直接適用できます。この手法を行内最適化と呼びます。

最適化後、クエリ プランにビットマップ フィルターが導入された場合、クエリのコンパイル時間は短縮されます。ただし、オプティマイザーが生成できるクエリ プランは制限され、基数やコストの見積もりは考慮されません。

最適化されたビットマップ フィルターには、次のような利点があります。

  • 複数のディメンション テーブルからのフィルターがサポートされます。

  • 1 つの操作に複数のフィルターを適用できます。

  • 最適化されたビットマップ フィルターは、さまざまな種類の操作に適用できます。たとえば、Distribute StreamsRepartition Streams などの交換操作のほか、テーブル スキャン、インデックス スキャン、フィルターなどの操作に適用できます。

  • SELECT ステートメントのほか、INSERT、UPDATE、DELETE、MERGE の各ステートメントで使用されている読み取り専用操作にフィルターを適用できます。

  • インデックス付きビューの作成で、インデックスを挿入するための操作にフィルターを適用できます。

  • オプティマイザーは、基数およびコストの推定により、最適化されたビットマップ フィルターが適切かどうかを判断します。

  • オプティマイザーはさまざまなプランを生成できます。

最適化されたビットマップ フィルターの実装方法

ビットマップ フィルターの効果が期待できるのは選択度が高い場合だけです。クエリ オプティマイザーは、どのような場合に、最適化されたビットマップ フィルターの選択度が効果を期待できる程度に高くなるか、また、どのような操作にフィルターを適用すべきかを判断します。オプティマイザーは、スター結合のすべての分岐に最適化されたビットマップ フィルターを設定し、コスト ルールを使用しながら、そのプランが最小の推定実行コストを提供するかどうかを判断します。最適化されたビットマップ フィルターの選択度が低かった場合、推定コストが高すぎるとして、そのプランは破棄されます。最適化されたビットマップ フィルターをプラン内のどこに配置すべきかを検討する際、オプティマイザーは、適切な深さのハッシュ結合のスタックなど、ハッシュ結合の派生形を探します。ディメンション テーブルとの結合が実装されて、最も選択度が高いと推定される結合が最初に実行されます。

最適化されたビットマップ フィルターが適用された操作には、PROBE([Opt_Bitmap1001], {[column_name]} [, 'IN ROW']) という形式のビットマップ述語が存在します。ビットマップ述語は、次の情報をレポートします。

  • Bitmap 操作で導入された名前に対応するビットマップ名。プレフィックス 'Opt_' は、最適化されたビットマップ フィルターが使用されていることを示します。

  • プローブの対象列。フィルター処理されたデータは、ここを起点としてツリーを通過します。

  • ビットマップ プローブで行内最適化が使用されるかどうか。使用される場合、ビットマップ プローブが IN ROW パラメーターで呼び出されます。それ以外の場合、このパラメーターは省略されます。

次の例は、単純なスター スキーマに対するクエリを表しています。単一の整数型列で主キー対外部キーの結合を使用し、DimProduct と DimCustomer という 2 つのディメンション テーブルを、ファクト テーブル FactInternetSales に結合します。

USE AdventureWorksDW2008R2;
GO
SELECT * 
FROM dbo.FactInternetSales AS F
INNER JOIN dbo.DimProduct AS D1 ON F.ProductKey = D1.ProductKey
INNER JOIN dbo.DimCustomer AS D2 ON F.CustomerKey = D2.CustomerKey
WHERE D1.StandardCost <= 30 AND D2.YearlyIncome <= 50000;

USE AdventureWorksDW2008R2;
GO
SELECT * 
FROM dbo.FactInternetSales AS F
INNER JOIN dbo.DimProduct AS D1 ON F.ProductKey = D1.ProductKey
INNER JOIN dbo.DimCustomer AS D2 ON F.CustomerKey = D2.CustomerKey
WHERE D1.StandardCost <= 30 AND D2.YearlyIncome <= 50000;

次の図は、SQL Server 2005 における、このクエリの実行プランを表しています。1A 地点では、既にディメンション テーブルがスキャンされており、条件に該当しない行をファクト テーブル (1B) から除外するための情報が把握されています。ただし、Table Scan 操作のプロパティは、ファクト テーブルから取得する行を制限するための述語が使用されていないことを示しています。

ビットマップ フィルターを使用しない SQL Server クエリ プラン。

一方、次の図は、SQL Server 2008 における、同じクエリの実行プランを表しています。最適化されたビットマップ操作は、両方のディメンション テーブルのサブツリーで使用されます。テーブル スキャン オペレーターのプロパティは、最初の結合操作の前に、これらのサブツリーからのフィルター (ビットマップ プローブ) が直接ファクト テーブル ツリーに適用され、ファクト テーブルから取得する行が制限されていることを示しています。

ビットマップ フィルターを使用する SQL Server クエリ プラン。

最適化されたビットマップ フィルターの要件

最適化されたビットマップ フィルターには、次の要件があります。

  • ファクト テーブルのページ数が 100 ページ以上あること。それより小さなテーブルは、オプティマイザーによってディメンション テーブルと見なされます。

  • ファクト テーブルとディメンション テーブル間の内部結合のみ考慮される。

  • ファクト テーブルとディメンション テーブル間の結合述語が単一列結合であること。主キー対外部キーの関係である必要はありません。整数ベースの列をお勧めします。

  • ディメンションとの結合は、ディメンションの入力基数が、ファクト テーブルの入力基数よりも小さい場合にのみ考慮される。