LIKEはインデックスを使用しますが、CHARINDEXは使用しませんか?


22

この質問は私の古い質問に関連しています。以下のクエリの実行には10〜15秒かかりました。

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [company].dbo.[customer]
WHERE (Charindex('123456789',CAST([company].dbo.[customer].[Phone no] AS VARCHAR(MAX)))>0) 

一部の記事では、インデックスを使用CASTしてCHARINDEXもメリットが得られないことがわかりました。またLIKE '%abc%'、インデックスを使用してもメリットはありませんが、インデックスを使用してもメリットがないという記事もありますLIKE 'abc%'

http://bytes.com/topic/sql-server/answers/81467-using-charindex-vs-like-where /programming/803783/sql-server-index-any-improvement-for -like-queries http://www.sqlservercentral.com/Forums/Topic186262-8-1.aspx#bm186568

私の場合、クエリを次のように書き換えることができます。

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [company].dbo.[customer]
WHERE [company].dbo.[customer].[Phone no]  LIKE '%123456789%'

このクエリは、前のクエリと同じ出力を提供します。columnの非クラスター化インデックスを作成しましたPhone no。このクエリを実行すると、わずか1秒で実行されます。これは、以前の14秒と比較して大きな変化です。

どのようにLIKE '%123456789%'インデックスからの利点は?

リストされた記事にパフォーマンスが改善されないと記載されているのはなぜですか?

使用するクエリを書き直そうとしましたCHARINDEXが、パフォーマンスはまだ遅いです。クエリのCHARINDEXように表示されるのに、なぜインデックス付けのメリットがないのLIKEですか?

を使用したクエリCHARINDEX

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
 FROM [Company].dbo.[customer]
 WHERE ( Charindex('9000413237',[Company].dbo.[customer].[Phone no])>0 ) 

実行計画:

ここに画像の説明を入力してください

を使用したクエリLIKE

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
 FROM [Company].dbo.[customer]
 WHERE[Company].dbo.[customer].[Phone no] LIKE '%9000413237%'

実行計画:

LIKEクエリプラン

回答:


28

LIKE '%123456789%'はどのようにインデックス化の恩恵を受けますか?

ほんの少しだけ。クエリプロセッサは、テーブル全体(クラスター化インデックス)の代わりに一致するものを探すために、非クラスター化インデックス全体をスキャンできます。一般に、非クラスター化インデックスは、それらが構築されているテーブルよりも小さいため、非クラスター化インデックスのスキャンが高速になる場合があります。

欠点は、非クラスター化インデックス定義に含まれていないクエリに必要な列は、行ごとにベーステーブルで検索する必要があることです。

オプティマイザーは、コストの見積もりに基づいて、テーブル(クラスター化インデックス)をスキャンするか、ルックアップを使用して非クラスター化インデックスをスキャンするかを決定します。推定コストは、オプティマイザーがユーザーまたは述部が選択する行数に大きく依存します。LIKECHARINDEX

リストされた記事にパフォーマンスが改善されないと記載されているのはなぜですか?

LIKEない状態ではないワイルドカードで始まる、SQL Serverが実行できる部分スキャン全体をスキャンするのではなく、インデックスのを。例えば、LIKE 'A%正しくのみインデックスレコードを試験することにより評価することができる>= 'A'< 'B'(正確な境界値は、照合に依存します)。

この種のクエリでは、bツリーインデックスのシーク機能を使用できます。bツリー>= 'A'を使用して最初のレコードに直接進み、< 'B'テストに失敗したレコードに到達するまでインデックスキーの順序で前方にスキャンできます。LIKE少ない行数にテストを適用するだけでよいため、一般にパフォーマンスが向上します。

対照的に、LIKE '%Aどこから開始または終了するかわからないため、部分スキャンに変換することはできません。どのレコードもで終わる可能性がある'A'ため、インデックス全体をスキャンしてすべての行を個別にテストすることは改善できません。

使用するクエリを書き直そうとしましたCHARINDEXが、パフォーマンスはまだ遅いです。CHARINDEXLIKEクエリのように見えるのに、なぜインデックス付けのメリットがないのですか?

クエリオプティマイザーは、どちらの場合も、テーブル(クラスター化インデックス)のスキャンと非クラスター化インデックス(ルックアップ付き)のスキャンのどちらかを選択できます。

選択は、コストの見積もりに基づいて2つの間で行われます。そのため、SQL Serverが2つの方法に対して異なる推定値を生成する場合があります。LIKEクエリの形式では、推定値は特別な文字列統計を使用して、かなり正確な推定値を生成できる場合があります。CHARINDEX > 0フォームは推測に基づく推定値を生成します。

オプティマイザがのクラスタ化CHARINDEXインデックススキャンとのルックアップ付き非クラスタ化インデックススキャンを選択するには、さまざまな推定値で十分LIKEです。CHARINDEXヒントを使用して非クラスター化インデックスを使用するようにクエリを強制すると、と同じプランが得られ、LIKEパフォーマンスはほぼ同じになります。

SELECT
    [Customer name],
    [Sl_No],
    [Id]
FROM dbo.customer WITH (INDEX (f))
WHERE 
    CHARINDEX('9000413237', [Phone no]) >0;

実行時に処理される行の数は両方のメソッドで同じになります。LIKEこの場合、フォームはより正確な推定を生成するため、クエリオプティマイザーはより適切なプランを選択します。

LIKE %thing%頻繁に検索が必要な場合は、SQL ServerのTrigram Wildcard String Searchで説明した手法を検討してください。


16

SQL Serverは、クエリでは使用できるが。では使用できない試行の形式で、文字列列の部分文字列に関する統計を維持しLIKEますCHARINDEX

詳細については、「文字列の要約統計」セクションを参照してください。

いくつかの重要な警告は、ワイルドカードのエスケープはESCAPEキーワードではなく独自の角括弧技術で行わなければならないことと、80文字より長い文字列では最初と最後の40文字のみが使用されることです。

WHERE ( Charindex('9000413237',[Company].dbo.[customer].[Phone no])>0 ) 

30%の行が返されるという不等式の述語に標準の推測を使用します。

LIKEクエリ(この場合)は、おそらく述語に一致する行がはるかに少ないと推定します。

先頭のワイルドカードは依然としてインデックスシークを妨げることに注意してください。インデックス全体がスキャンされますが、クラスター化インデックスよりも狭い別のインデックスが使用されます。狭いインデックスはクエリで使用されるすべての列をカバーしていないため、2番目のプランでは、欠落している列を取得するためにキールックアップが必要です。

この計画が30%の見積もりで選択されることはほとんどありません。SQL Serverは、クラスター化インデックス全体をスキャンし、そのような多くのルックアップを避ける方が安価であると見なします。その他の例については、転換点に関するこの記事を参照してください。


あなたの説明がわかりません。likeの使用はcharindexよりも優れていると言っていますか?
IT研究

3
@ITresearcher -はい、潜在的に、だけではなく、(条件に一致する行数のブランケット推測を使用しての30%)それは見ることができLIKE、パターン供給された文字列の要約統計量とより正確な推定値を導出します。それを武器に、別のより適切な計画を選択するかもしれません。
マーティンスミス

3
...または、「最悪の場合」、同じ計画。
アーロンバートランド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.