概要:インデックスの内部構造と応用概念を理解しよう
SQL Serverでパフォーマンスを最適化する上で、インデックスの内部構造を理解することは欠かせません。
単にインデックスを作成するだけではなく、その内部でどのようにデータが格納・参照されるかを把握することで、より効率的な設計が可能になります。
この記事では、ヒープ構造・ページ分割・フィルターインデックスといった高度なテーマを中心に、実務的な最適化ポイントを解説します。
目次
ヒープ構造とは:クラスタ化インデックスがないテーブルの内部
クラスタ化インデックスが存在しないテーブルを、SQL Serverではヒープ(Heap)と呼びます。
ヒープでは、行データが挿入順にページへ格納され、行を特定するためにRID(Row Identifier)が使用されます。
RIDはファイルID・ページID・スロット番号で構成され、クラスタ化キーの代わりに物理的な位置でレコードを特定します。
ヒープ構造は挿入処理が速い一方で、削除や更新が頻発すると断片化が進行しやすいという特徴があります。
もし断片化が深刻化した場合は、次のようなコマンドで再構成を行うことが可能です。
ALTER TABLE dbo.Sales REBUILD;
ヒープを長期的に維持するのは推奨されません。
特定の用途(ログテーブルなど)を除き、クラスタ化インデックスを作成しておくことが一般的です。
ページ構造の理解:Bツリーの仕組みとページ分割
SQL Serverのインデックスは、Bツリー構造を基礎にしています。
インデックスはルートページ・中間ページ・リーフページで構成され、各ページは8KB単位の固定サイズで管理されます。
データが増加し、ページが満杯になると、新しいページが自動で割り当てられます。これがページ分割(Page Split)です。
ページ分割は、更新や挿入時のパフォーマンス低下を引き起こす原因にもなります。
これを緩和するには、次のようにFILLFACTORを設定して、ページに余白を残す方法が有効です。
CREATE CLUSTERED INDEX IX_Sales_OrderDate
ON dbo.Sales(OrderDate)
WITH (FILLFACTOR = 90);
この設定により、将来の挿入に備えて各ページに10%の空きを確保します。
FILLFACTORを適切に調整することで、ページ分割の発生頻度を大幅に抑えられます。
フィルターインデックスとは:部分的なインデックス最適化
フィルターインデックス(Filtered Index)は、WHERE句で条件を限定した部分インデックスです。
テーブル全体ではなく一部の行のみを対象にすることで、ストレージ使用量を減らし、検索を高速化できます。
例えば、以下のようなインデックスは「請求済みデータ」のみを対象にします。
CREATE NONCLUSTERED INDEX IX_Billing_Paid
ON dbo.Billing(PaymentDate)
WHERE PaymentStatus = 'PAID';
このように条件を絞ることで、特定のクエリに最適化された効率的な検索が可能です。
ただし、クエリ側の条件が完全一致しないと利用されない点に注意が必要です。
運用前には実行計画を確認して、フィルターインデックスが実際に利用されているかを検証しましょう。
実行計画で確認するインデックスの利用状況
SQL Server Management Studio(SSMS)で実行計画を有効化すると、インデックスがどのように利用されているかを確認できます。
代表的な演算子には以下の2つがあります。
- Index Seek:条件に一致した範囲を効率的に検索(理想的な動作)
- Index Scan:テーブル全体を走査(パフォーマンス低下の要因)
また、実行計画には「Missing Index」の提案も表示される場合があります。
ただし、自動提案をそのまま採用すると過剰インデックスを招くこともあるため、実際のアクセス頻度や更新コストを考慮する必要があります。
実行計画XMLを確認することで、どのインデックスが参照され、どの統計情報が利用されているかをより詳細に把握できます。
インデックス設計時の実務的ポイント
インデックスは検索速度を向上させますが、多すぎると更新・挿入処理が遅くなるというトレードオフがあります。
そのため、業務シナリオに応じたバランス設計が重要です。
- 複合インデックス:検索条件の列順序を慎重に設計する
- 統計情報:自動更新設定を有効化し、定期的に再構築する
- メンテナンス:ALTER INDEX ... REORGANIZE / REBUILDを定期実行
例えば、定期メンテナンスジョブとして次のようなスクリプトを組むと効果的です。
ALTER INDEX ALL ON dbo.Sales REORGANIZE;
UPDATE STATISTICS dbo.Sales;
これにより断片化を防ぎ、常に最適なクエリパフォーマンスを維持できます。
まとめ:適切なインデックス戦略で高速化を実現
SQL Serverのインデックス構造を理解すると、チューニングの精度が大きく向上します。
ヒープ構造は単純ですが更新に弱く、ページ分割は性能劣化を招く要因になります。
フィルターインデックスを活用すれば、対象範囲を絞った効率的な検索が可能です。
常に実行計画を確認しながら、最適なインデックス戦略を選択することが高速化の鍵です。
参考リンク(公式ドキュメント)

0 件のコメント:
コメントを投稿