2009-05-12 7 views
3

ms sqlサーバーのクエリに問題があります。私は "col1"という列にフルテキストインデックスを持っています。この列のデータはかなり大きくなる可能性があります(20,30 kb +)。この列で正確なフレーズを検索したいと考えています。SQL Server: 'contains' vs 'charindex'

"contains"関数がこれのための最も速い関数だと言われましたが、私はこれを行うための少なくとも2つの方法を知っています。 "like"関数を使用し、 "charindex"を使用します。

問題は、#記号を含むフレーズを検索しているときに "contains"が機能しないことです。たとえば、 "... WHERE contains(col1、 '" query string# "')..."は常に0の結果を返します。

私はcharindexを使用するように切り替えましたが、結果は返されますが、この関数を使用してデータベースを照会するにはかなり時間がかかります。

このクエリを高速化するか、contains関数で#記号を受け入れる方法はありますか?私は機能が含まれていCHARINDEX使用して切り替えることにしましたお時間を

おかげで...

更新 。したがって、クエリデータに#記号が含まれている場合は、charindexを使用します。他のすべてのクエリでは、containsを使用します。最高の仕事をするようです。

答えて

2

FTSの独自の実装でも同様の問題があります。これは、マイクロソフトがインデックス作成ルーチンから多くの特殊文字や一般的な単語を取り除くためです。

私たちの状況では、入力を制御し、ハッシュ記号などの特殊文字を変換する関数を通してすべてのテキストを渡します。したがって、ハッシュ記号のデータベースへの入力は、この "zxzHASHyxy"のようになります。

次に、検索を実行するときに翻訳版を「本物の」バージョンに置き換えることができます。

しかし、この実装には大きな欠点があります。翻訳されていないテキストのコピーを保持する必要がある場合は、別の列でそれを行わなければならず、それがデータベースに膨らんでしまいます。

この解決策は控えめに使用してください。

+0

、非常に興味深いですそのことを考えたことがないが、それは私の場合では動作しません。データベースはいくつかの異なるアプリケーションに使用されており、データベースの値を変更することはできません。 – user85116

1

「#」などの特殊文字は単語区切り文字で、インデックスには含まれません。フルテキストインデックス作成のために、 'query string#xyz'は 'query string xyz'のように見えます。

あなたはFREETEXT機能を使用するように試みることができる:

FREETEXTを使用するフルテキストクエリは、それらの全文 クエリより 少ない正確​​で使用して含まれています。 SQL Serverの フルテキスト検索エンジンは、重要な単語と語句を と識別します。いいえ 予約キーワードまたはワイルドカード 文字には、CONTAINS述語の パラメータ に指定されていると、通常は意味がある 文字のいずれかに特別な意味が与えられます。

+0

多分私はSQLの教祖の十分ではないが、それはmsのSQLサーバーで実装されているような機能を含むことはかなり欠陥があるようだ。正確なフレーズを検索したい場合は、そのための(高速)オプションが必要です。MSが単語区切りなどと思うものは気にしないでください。私はFREETEXTがファジーマッチングに役立つかもしれないが、それでも私のためにはあまりにもあいまいであることがわかります。私がこれらの2つの関数を構築した方法は、私のタイプのクエリにとっては無用です。 – user85116

0

CHARINDEX()関数の代わりにLIKE演算子/述語を使用してテストを実行しましたか?LIKEはCHARINDEX()より速いと私は期待していますが、それを裏付ける証拠や文書はありません。

さらに:

  • は#記号自体は、クエリで実際に重要なのですか?
  • これは、SQLのCONTAINS()を使用してクエリ文字列(#がある場合とない場合)を含むすべてのレコードの一覧を取得し、次にアプリケーション側のテストを行う2段階の問題を使用できますか。 #を持たないエントリを削除しますか?
+0

私はちょうど試しました。 LIKEは恐ろしいです(およそ15,297msで来ます)。次はCHARINDEX(2828 ms)であり、最後には最も速く(97 ms)です。 アプリケーション側の操作の提案は面白いですが、うまくいかないでしょう。たとえばTOP関数と統合しようとすると複雑になるでしょう。 – user85116

-1
ALTER FULLTEXT INDEX ON [dbo].[Tablename] SET STOPLIST = OFF 

これは、内部含まれている特殊文字を使用するのに役立ちます。

例:

select * from [dbo].[Tablename] where contains(Column_Name,'C# or C++') 
関連する問題