SQL Serverユーザーは、「sargable」という用語を使用します。「sargable」の客観的な実装に依存しない時代を超越した定義があるかどうか疑問に思っています。
たとえば、WHERE foo LIKE '%bar%'
多くの人からsargableではないと言われていますが、一部のRDBMS はそのようなクエリでインデックスを使用できます。その後、何「検索引数可能ではない」意味ですか?
その他の参考文献
SQL Serverユーザーは、「sargable」という用語を使用します。「sargable」の客観的な実装に依存しない時代を超越した定義があるかどうか疑問に思っています。
たとえば、WHERE foo LIKE '%bar%'
多くの人からsargableではないと言われていますが、一部のRDBMS はそのようなクエリでインデックスを使用できます。その後、何「検索引数可能ではない」意味ですか?
その他の参考文献
回答:
「sargable」という用語は、P。Griffiths Selingerらによって最初に導入されました。ACMが発行した1979年の論文「リレーショナルデータベース管理システムにおけるアクセスパスの選択」。非ACMメンバーの場合は、http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdfにその論文のコピーがあります。
用語はこの段落で定義されています:
インデックススキャンとセグメント1スキャンの両方で、オプションで検索引数(またはSARGS)と呼ばれる一連の述語を使用できます。これらは、RSI 2呼び出し元に返される前にタプルに適用されます。タプルが述部を満たす場合、タプルが返されます。それ以外の場合、SARGSを満たすタプルが見つかるか、セグメントまたは指定されたインデックス値の範囲を使い果たすまでスキャンが続行されます。これは、RSS内で効率的に拒否できるタプルのRSI呼び出しを行うオーバーヘッドを排除することにより、コストを削減します。すべての述部がSARGSになり得る形式ではありません。検索引数可能述部は、フォームの1つ(または形態に入れることができる)「欄比較演算子値」です。SARGSは、選言標準形のそのような述部のブール式として表されます。
つまり、sargable述語は、テーブルまたはインデックスレコードを直接監視することにより、ストレージエンジン(アクセス方法)によって解決できるようなものです。逆に、非サーガブル述語では、アクションを実行するためにより高いレベルのDBMSが必要です。たとえば、各レコードのWHERE lastname = 'Doe'
フィールドlastname
の内容を調べるだけで、ストレージエンジンが結果を決定できます。一方、WHERE UPPER(lastname) = 'DOE'
SQLエンジンによる関数の実行が必要です。つまり、ストレージエンジンは、読み取りのためにすべての行を返す必要があります(他の可能性のある検索引数と一致する場合)。 。
元の定義から、「列比較演算子の値」の条件が満たされているため、sargable述語はインデックススキャンだけでなく、テーブル(System R用語ではセグメント)スキャンにも適用できることがわかります。ストレージエンジンによって評価されます。これは、多くの点でSystem Rの子孫であるDb2の場合です。
インデックスsargable述語は検索のブラケットには使用されませんが、選択された場合はインデックスから評価されます。これは、述語に含まれる列がインデックスキーの一部であるためです。これらの述語も、インデックスマネージャーによって評価されます。
データ検索可能述語は、インデックスマネージャでは評価できないが、データ管理サービス(DMS)で評価できる述語です。通常、これらの述語は、ベーステーブルから個々の行にアクセスする必要があります。必要に応じて、DMSは述語の評価に必要な列を取得し、
SQL Serverで言えば、sargable述語はインデックスシークを使用して解決できるものだけであるという事実は、おそらくテーブルスキャン中にストレージエンジンがそのような述語を適用できないことによって決まります。
SargableおよびNon-sargableの述語は、それぞれ「ステージ1」および「ステージ2」の述語として記述される場合があります(これはDb2用語から来ています)。ステージ1の述語は、テーブルまたはインデックスレコードを読み取りながら、クエリ処理の最低レベルで評価できます。ステージ1の条件に一致する行がある場合は、次のレベルである評価のステージ2に送信されます。
1-システムRのセグメントは、テーブルのタプルの物理ストレージです。セグメントスキャンは、他のDBMSのテーブルスキャンと多少同等です。
2 -RSI-RSS 3インターフェイス、タプル指向のクエリインターフェイス。この説明に関連するインターフェイス関数はNEXTで、クエリ述語に一致する次の行を返します。
3 -RSS、またはResearch Storage System、System Rのストレージサブシステム
= UPPER()
関数呼び出しですがmemcmp
、それ自体はそうです。memcmp
ASCIIを想定し、大文字小文字を無視するを書くのは比較的簡単です(2番目のニブルを見てください)。それでSARGABLEになりますか?@Ypercubeの例、dba.stackexchange.com
x=0
SARG は可能ですか?何について-0 = +0
、' ' = ''
または空間的平等?確かにSARG可能なものの例は何でしょうか?「ストレージエンジンの外部に実装されたデータベース関数に頼らずに」と言うときDATE()
、ストレージエンジン内に含まれているYpercubeの例に含まれています。なぜそれだけでSARGできないのですか?
DATE()
は実際の(SQL Server)関数ではなく、(私が推測した)型変換のためのMr. Cubeの速記です。必要に応じて、チャットでこれについて議論することもできます。
私にとって、SARGableは、SQL Serverが検索述語を使用してインデックスシークを実行できることを意味します。
DBMSがインデックスを「活用」できると言うことはできません。なぜなら、非サーガブル述語では、SQL Serverが非クラスター化インデックスをスキャンする可能性があるためです。
Dmitri KorotkevitchによるPro SQL Server Internalsによると:
検索引数ABLE述語は、インデックスが存在する場合、SQL SERVERがインデックスシーク操作を利用できる述語です。
SARGable述語は、SQLサーバーが単一の値または処理するインデックスキー値の範囲を分離できるものです。
検索引数可能述語は次の演算子が含まれる:
=
、>
、>=
、<
、<=
、IN
、BETWEEN
、及びLIKE
(プレフィックスマッチングの場合)非検索引数可能オペレータは:
NOT
、NOT IN
、<>
、及びLIKE
(ないプレフィックスマッチング)、ならびにテーブルに対して機能または計算の使用、およびデータ型が作成されたインデックスを満たしていないタイプの変換を。
例:
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クエリのプロパティを見てみましょう(インデックスシーク)
クエリオプティマイザーは、開始と終了のインデックスに制限を定義できます。クエリする検索引数があります。
次に、SARGに対応していないクエリ:
述語「%non ..%」の先頭で、クエリオプティマイザーがインデックスの開始と終了、または範囲を定義できないことを確認できます。テーブル全体を検索する必要があります(スキャン)。
WHERE name like '%non-SARGable%'
繰り返しますが、条件を検索可能にするインデックスを後で作成する場合、そして、もしそうなら、私たちは特定の実装の欠点について話していませんか?IE。、「SQL Server 2016の時点では引数を指定できません」と言うべきではない
WHERE DATE(datetime_column) = '2001-01-01'
たとえば、新しいSQL Serverバージョン(2008+と思う)では "sargable"(インデックスシークを行います)ですが、古いバージョンではそうではありません。