最初にワイルドカードを使用してLIKEを使用してクエリを実行するSQL Serverのデータベースモデルを最適化する方法を知りたいと思います。私はDBのエキスパートではないので、インデックスやその他の最適化の使用に関するアドバイスは大歓迎です。ワイルドカードを使用した高速LIKEクエリのDBモデルの最適化方法
状況:この表は300000+レコードが含ま
ShortNameEN (varchar(50))
ShortNameFR (varchar(50))
ShortNameDE (varchar(50))
ShortNameNL (varchar(50))
LongNameEN (varchar(250))
LongNameFR (varchar(250))
LongNameDE (varchar(250))
LongNameNL (varchar(250))
: 私は、次の列を持つテーブル '製品' を持っています。
にはの検索文字列(ShortNameENでのみ)が含まれているレコードを見つけるためにselect文を書く必要があります。 私のクエリは
SELECT *
FROM Products
WHERE ShortNameEN LIKE '%searchstring%'
です。もちろん、このクエリは非常に遅いです。 ShortNameENにインデックスを追加することは、最初のワイルドカードのために使用されないため、役に立たない。
質問1: ShortNameEN列を他の表と分けるのは意味がありますか?私は、ディスクアクセス/行サイズ/ページサイズと、これがパフォーマンスにどのように影響するかについて全く知らない。おそらく、ここでパフォーマンスを向上させることができる他のファイルシステム関連の最適化がありますか?
一時的な解決策は、私は創造的な「トライグラム」ソリューションを見つけましたが、私のモデルにかなりの影響を与えます。このために私は私の最初のテーブルを参照する第二表「ProductNameFragments」を作成し、すべてのShortNameEN、次のようにブレークダウン:のProductId = 123、ShortNameEN =「プリンタ」
ProductId | NameFragment
123 | PRINTER
123 | RINTER
123 | INTER
123 | NTER
123 | TER
123 | ER
123 | R
トリガーのため
例ProductテーブルはProductNameFragmentsテーブルを同期します。
このようにして、2つのテーブルに参加し、最初のワイルドカードなしでクエリできます。
SELECT p.*
FROM Product p, ProductNameFragment pnf
WHERE p.Id = pnf.ProductId
AND pnf.NameFragment LIKE '%searchstring%'
最初のテストでは、検索クエリのパフォーマンスが大幅に向上することがわかりました。
質問2:通常のインデックスまたはProductNameFragmentのクラスタードインデックスを使用します製品の更新/削除/挿入時のパフォーマンスへの影響はどのようになりますか? 1つの製品名を更新すると、ProductNameFragmentsテーブルに50の削除と50の挿入が発生する可能性があります。インデックスを強制的に更新することはできますか?
最後に、私は複雑さのために、「トリグラム」ソリューションを使用しないことをお勧めします。だから、ヒントやトリックは歓迎以上のものです。予め
Thxを
スティーブン一般
フルテキスト検索:https://docs.microsoft.com/en-us/sql/relational-databases/search/full-text-searchから始めます。 –
今日のヒント:現代的で明示的な 'JOIN'構文に切り替えます。書き込みが簡単(エラーなし)、読みやすく保守が容易、必要に応じて外部結合に変換する方が簡単です。 – jarlh
フルテキスト検索を使用することをお勧めします。https://docs.microsoft.com/en-us/sql/relational-databases/search/full-text-search –