by Hayato Matsuura.

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


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)

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

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ラベルがフィルタ述語を表しています。

ヒント

著者について

Markus Winandの写真

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

彼の本

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

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

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

Amazonで購入
(印刷版のみ)

Do not use offset for pagination

Learn why

Visit my sibling!A lot changed since SQL-92!

Use The Index, Luke のカップは

ステッカー、コースター、本、コーヒーマグ。 学習に必要なものすべて。

今すぐ購入

Connect with Markus Winand

Markus Winand on LinkedInMarkus Winand on XINGMarkus Winand on Twitter
“Use The Index, Luke!” by Markus Winand is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
法律上の通知 | お問い合わせ | 無保証 | 商標 | プライバシーとGDPR | CC-BY-NC-ND 3.0 license