2009-04-29 5 views
2

最も一般的なデータベースのSQL LIKE演算子の複雑さは誰にも分かりますか?SQL `LIKE`の複雑さ

+0

「複雑さ」の意味を明確にしてください。 –

+0

申し訳ありません、私は友人を求めていましたが、彼は大きなOを意味しましたが、それはすべて私が知っていることです。 – GhassanPL

答えて

10

3つのコアケースを別々に考えてみましょう。この議論はMySQL固有のものですが、インデックスは通常同様の方法で実装されているため、他のDBMSにも当てはまります。

LIKE 'foo%'は、索引付けされた列で実行すると高速です。 MySQLインデックスはBツリーのバリエーションです。このクエリを実行すると、ツリーは単にfooに対応するノード、またはその接頭辞を持つ最初のノードに降りて、ツリーを前方に移動できます。これはすべて非常に効率的です。

LIKE '%foo'は、索引によって高速化することはできず、全表スキャンとなります。インデックスを使用して実行できる他の基準がある場合、最初のフィルタリング後に残っている行のみをスキャンします。

しかしトリックがあります:あなたは接尾辞マッチングを行う必要がある場合 - 例えば、拡張子.fooとファイル名を検索 - あなたは、元の1としてではなくて同じ内容でカラムを追加することによって、同じ性能を達成することができます文字は逆の順序で表示されます。その後、.fooで終わるcolを持つ行を検索する

ALTER TABLE my_table ADD COLUMN col_reverse VARCHAR (256) NOT NULL; 
ALTER TABLE my_table ADD INDEX idx_col_reverse (col_reverse); 
UPDATE my_table SET col_reverse = REVERSE(col); 

は次のようになります。

SELECT * FROM my_table WHERE col_reverse LIKE 'oof.%' 

最後に、近道はありませんそのためLIKE '%foo%'は、あります。行数を実現可能な数値に減らす他の制限基準がない場合、パフォーマンスが低下します。代わりにフルテキスト検索ソリューション、またはその他の特殊なソリューションを検討することもできます。

+0

を意味するのではなく、 'oof%'のようなcol_reverseですか? ? –

+1

col_reverseに 'oof%'は必要ありませんか?また、第2のクエリ断片は、第1の質問断片とは異なる質問に答える。 –

+3

"col LIKE '%foo%'"は、フィールド内の任意の場所にある "foo"の出現と一致します。 "col LIKE 'foo%' OR col_reverse LIKE 'oof%'"は、これらの結果のサブセット(フィールドが "foo"で始まる、または "foo"で終わる)にのみ一致します。 – LukeH

1

RDBMS、データ(および場合によってはデータのサイズ)、インデックス、およびLIKEの使用方法(接頭辞のワイルドカードの有無)によって異なります。

あなたはあまりにも一般的な質問をしています。

+0

ええ、私は考えましたが、それは友人のための質問であり、彼は私にもっと教えてくれませんでした。 – GhassanPL

1

あなたは、パフォーマンスへの影響について尋ねている場合:

のような問題は、それがインデックスを使用してからデータベースを保持していることです。 Oracleではインデックスをもう使用しないと思いますが(私はまだOracle 9上にいます) SqlServerは、ワイルドカードが最後にある場合のみインデックスを使用します。私は他のデータベースについて知らない。

+0

インデックス上のランダムアクセスを防止しますが、インデックスをスキャンしないでください(ただし、使用するインデックスが変更される可能性があります)。 –

+0

あなたは何を意味するのか分かりません。インデックス全体をスキャンして(そして後でテーブルに参加する)、実際のテーブルをスキャンするほうが速くはありませんか? –

+0

インデックス全体をスキャンして後でテーブルに結合すると、実際のテーブルをスキャンするよりもずっと高速になる可能性があります。インデックスは通常、テーブルよりも狭く、データベースページにはより多くの「レコード」が収まります。 –