SQL Serverユーザー ( "sargable")という用語を使用 。 「サーガブル」の客観的な実装にとらわれない時代を超越した定義があるかどうか疑問に思っています。
例えば、 WHERE foo LIKE '%bar%'
は多くの人が sargable であると言いますが、一部のRDBMS そのようなものでインデックスを使用できますクエリ 。次に、「検索できない」はどういう意味ですか?
その他の参考資料
「sargable」という用語は、P。Griffiths Selingerらによって最初に導入されました。 1979年の論文「リレーショナルデータベース管理システムでのアクセスパスの選択」で、 ACMから発行 。非ACMメンバーの場合は、その論文のコピーが http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf にあります。
この用語はこの段落で定義されています。
インデックスとセグメントの両方1 スキャンはオプションで、RSIに返される前にタプルに適用される、検索引数(またはSARGS)と呼ばれる一連の述語をとることができます。2 発信者。タプルが述部を満たす場合、それが返されます。それ以外の場合、スキャンは、SARGSを満たすタプルが見つかるか、セグメントまたは指定されたインデックス値の範囲を使い果たすまで続行されます。これにより、RSS内で効率的に拒否できるタプルのRSI呼び出しを行うオーバーヘッドがなくなるため、コストが削減されます。すべての述部がSARGSになる可能性がある形式であるとは限りません。 sargable predicateは、「列比較演算子値」の形式(または形式に入れることができる)の1つです。 SARGSは、そのような述語の論理式として選言標準形で表現されます。
つまり、検索可能な述語は、ストレージエンジン(アクセスメソッド)がテーブルまたはインデックスレコードを直接監視することで解決できる述語です。逆に、引数なしの述語は、アクションを実行するために、より高いレベルのDBMSを必要とします。たとえば、_WHERE lastname = 'Doe'
_の結果は、ストレージエンジンが各レコードのフィールドlastname
の内容を確認するだけで決定できます。一方、WHERE UPPER(lastname) = 'DOE'
は、SQLエンジンによる関数の実行を必要とします。つまり、ストレージエンジンは、読み込んだすべての行を返す必要があります(他の検索可能な述語と一致する場合)。評価のために、追加のCPUコストが発生します。
元の定義から、条件「列の比較演算子の値」が満たされ、したがって条件が満たされる限り、検索可能な述語はインデックススキャンだけでなく、テーブル(システムR用語ではセグメント)スキャンにも適用できることがわかります。ストレージエンジンによって評価されます。これは確かに、システムRの子孫であるDb2の場合です 多くの点で :
述語に含まれる列はインデックスキーの一部であるため、インデックス検索可能な述語は検索を括弧で囲むために使用されませんが、選択された場合はインデックスから評価されます。これらの述語は、インデックスマネージャによっても評価されます。
データ検索可能な述語は、インデックスマネージャでは評価できないが、データ管理サービス(DMS)では評価できる述語です。通常、これらの述語には、ベーステーブルの個々の行へのアクセスが必要です。必要に応じて、DMSは述語の評価に必要な列を取得します。
SQL Serverで言えば、引数指定可能な述語はインデックスシークを使用して解決できるものだけであるという事実は、おそらくストレージエンジンがテーブルスキャン中にそのような述語を適用できないことによって決定されます。
検索条件付きおよび検索条件設定不可の述語は、それぞれ「ステージ1」および「ステージ2」の述語として記述される場合があります(これは Db2用語 にも由来します)。ステージ1述部は、テーブルまたはインデックスレコードを読み取りながら、クエリ処理の最低レベルで評価できます。ステージ1の条件に一致する行がある場合、それは評価の次のレベルであるステージ2に送られます。
1 -システムRのセグメントは、テーブルのタプルの物理的なストレージです。セグメントスキャンは、他のDBMSのテーブルスキャンと同等です。
2 -RSI-RSS3 タプル指向のクエリインターフェイスであるインターフェイス。この説明に関連するインターフェース関数はNEXTであり、クエリ述語に一致する次の行を返します。
3 -RSS、またはリサーチストレージシステム、システムRのストレージサブシステム。
私にとってSARGableは、SQL Serverが検索述語を使用してインデックスシークを実行できることを意味します。
引数なしの述語を使用すると、SQL Serverはクラスタ化されていないインデックスをスキャンしてしまう可能性があるため、DBMSがインデックスを「活用」できるとは言えません。
Pro SQL Server Internalsby Dmitri Korotkevitch によると:
検索引数ABLE述語は、インデックスが存在する場合、SQL SERVERがインデックスシーク操作を利用できる述語です。
SARGable述語は、SQLサーバーが処理するインデックスキー値の単一の値または範囲を分離できる述語です。
SARGable述語には、次の演算子が含まれます:
=
、>
、>=
、<
、<=
、IN
、BETWEEN
、およびLIKE
(プレフィックス一致の場合)非SARGable演算子には、
NOT
、NOT IN
、<>
、LIKE
(not prefix matching)、テーブルに対する関数または計算の使用、およびデータ型が作成されたインデックスを満たさない場合の型変換。
例:
WHERE name like 'SARGable%'
WHERE name like '%non-SARGable%'
デモ:
DROP TABLE dbo.Testing;
GO
CREATE TABLE Testing (
WeirdDatatype int NOT NULL,
SomethingElse char(200)
);
CREATE NONCLUSTERED INDEX IDX_ALWAYS_SARGable
ON dbo.Testing( SomethingElse);
CREATE NONCLUSTERED INDEX IDX_NOT_ALWAYS_SARGable
ON dbo.Testing(SomethingElse);
INSERT INTO dbo.Testing
( WeirdDatatype, SomethingElse )
SELECT TOP 1000 m.message_id, CONVERT(char(200), m.text)
FROM sys.messages AS m;
今実行します:
SELECT *
FROM dbo.Testing AS t
WHERE t.WeirdDatatype = 1001;
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE 'Line%'
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE '%Line%'
AND t.WeirdDatatype = 1001;
結果は次のとおりです。
SARGableクエリ(Index Seek)のプロパティを見てみましょう
クエリオプティマイザーは、開始と終了のインデックスに制限を定義できます。照会する検索引数があります。
次に、SARGableでないクエリ:
述語 '%non ..%'の先頭では、クエリオプティマイザーはインデックスの開始または終了または範囲を定義できません。これで、テーブル全体を検索する必要があります(スキャン)。