SQL Serverは、where
句(述語)を適用するのに、
3つの方法を使い分けます。
- アクセス述語 (「Seek Predicates」)
アクセス述語は、リーフノードの走査の開始と終了の条件を表しています。
- インデックスフィルタ述語 (インデックス操作に対する「Predicates」または 「where」)
インデックスフィルタ述語は、リーフノード走査の時にのみ適用されます。スキャンされる範囲の開始と終了の条件を表したり、 範囲を狭めるものとしては使われません。
- テーブルレベルのフィルタ述語 (テーブル操作に対する「where」)
インデックスの一部でない列に対する述語は、テーブルのレベルで評価されます。その場合データベースは、 まずテーブルから行をロードしなければなりません。
この節では、SQL Serverの実行計画から フィルタ述語を見つける方法について説明します。第3章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)
例文では、SECTION
とID2
で選択しています。
SELECT count(*)
FROM scale_data
WHERE section = @sec
AND id2 = @id2
グラフィカルな形式での実行計画
グラフィカルな実行計画では、マウスをIndex Seek
の
処理の上に持って来た時だけ表示されるツールチップ内に述語情報は隠れてしまっています。述語情報を見るには、このページの図のように、Index Seek
アイコンの上に
マウスを動かす必要があります。
SQL ServerのSeek Predicatesは、 Oracleのアクセス述語に当たるもので、リーフノードの走査範囲を狭めます。フィルタ述語はSQL Serverのグラフィカルな形式の実行計画では、 単にPredicatesとだけラベルされます。
協力してください
この記事が気に入ったら、私の書いた本「SQLパフォーマンス詳解」や私によるトレーニングもきっと気にいるはず。
テーブル形式での実行計画
テーブル形式での実行計画では、処理が書かれたのと同じ列に 述語情報が表示されます。一度に関連する情報を全てコピーアンドペーストするのに便利です。
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
ラベルがフィルタ述語を表しています。