by Hayato Matsuura.

アクセス述語とフィルタ述語の見分け方


SQL Serverは、where句(述語)を適用するのに、 3つの方法を使い分けます。

アクセス述語 (「Seek Predicates」)

アクセス述語は、リーフノードの走査の開始と終了の条件を 表しています。

インデックスフィルタ述語 (インデックス操作に対する「Predicates」 または 「where」)

インデックスフィルタ述語は、リーフノード走査の時にのみ適用されます。 スキャンされる範囲の開始と終了の条件を表したり、 範囲を狭めるものとしては使われません。

テーブルレベルのフィルタ述語 (テーブル操作に対する「where」)

インデックスの一部でない列に対する述語は、 テーブルのレベルで評価されます。その場合データベースは、 まずテーブルから行をロードしなければなりません。

この節では、SQL Serverの実行計画から フィルタ述語を見つける方法について説明します。第3章フィルタ述語の 影響について説明したサンプルを使います。付録に、テーブルやデータを生成するスクリプトがあります。

CREATE TABLE scale_data (
   section NUMERIC NOT NULL,
   id1     NUMERIC NOT NULL,
   id2     NUMERIC NOT NULL
)
CREATE INDEX scale_slow ON scale_data(section, id1, id2)

例文では、SECTIONID2で選択しています。

SELECT count(*)
  FROM scale_data
 WHERE section = @sec
   AND id2 = @id2

グラフィカルな形式での実行計画

グラフィカルな実行計画では、マウスをIndex Seekの 処理の上に持って来た時だけ表示されるツールチップ内に述語情報は 隠れてしまっています。述語情報を見るには、 このページの図のように、Index Seekアイコンの上に マウスを動かす必要があります。

SQL ServerのSeek Predicatesは、 Oracleのアクセス述語に当たるもので、リーフノードの走査範囲を狭めます。 フィルタ述語はSQL Serverのグラフィカルな形式の実行計画では、 単にPredicatesとだけラベルされます。

テーブル形式での実行計画

テーブル形式での実行計画では、処理が書かれたのと同じ列に 述語情報が表示されます。一度に関連する情報を全てコピーアンドペーストするのに 便利です。

DECLARE @sec numeric
DECLARE @id2 numeric
SET STATISTICS PROFILE ON
SELECT count(*)
  FROM scale_data
 WHERE section = @sec
   AND id2 = @id2
SET STATISTICS PROFILE OFF

実行計画は、結果ペインの2番目の結果セットとして表示されます。 読みやすさのために少しだけフォーマットを変えてありますが、 次の例はStmtText列の内容を表しています。

|--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(...))
     |--Stream Aggregate(DEFINE:([Expr1008]=Count(*)))
          |--Index Seek(OBJECT:([scale_data].[scale_slow]),
             SEEK: ([scale_data].[section]=[@sec])
                    ORDERED FORWARD
             WHERE:([scale_data].[id2]=[@id2]))

SEEKラベルがアクセス述語である事を表し、 WHEREラベルがフィルタ述語を表しています。

ヒント

著者について

Markus Winandの写真

Markus Winand氏は、開発者がSQLパフォーマンスを改善するお手伝いをしています。彼は、SQL Performance Explainedの 著者でもあり、出張トレーニングhttp://winand.at/での リモート講義も 行っています。

彼の本

カバー『SQLパフォーマンス詳解』

核心をわかりやすく 解説。

Markusから購入します
(送料無料+PDF)

Amazonで購入
(印刷版のみ)

“Use The Index, Luke!” by Markus Winand is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
法律上の通知 | 接触 | 無保証 | 商標 | Privacy | CC-BY-NC-ND 3.0 license