3

ASP.NET MVC アプリケーションに取り組んでいます。このアプリケーションは 200 人のユーザーが使用しています。これらのユーザーは、常に (5 分ごとに) 100,000 個のアイテムのリストからアイテムを検索します (このリストは毎月 1 ~ 2 % ずつ増加します)。この 100,000 項目のリストは、SQL Server テーブルに格納されています。

検索はワイルドカード検索です

例えば:

Select itemCode, itemName, ItemDesc 
from tblItems
Where itemName like '%SearchWord%'

主な業務はアイテムの検索と選択に依存しているため、検索は非常に高速である必要があります。

最高のパフォーマンスを得る方法を知りたいです。検索結果は瞬時に表示される必要があります。

私が試したこと -

  1. 100,000 レコード全体を memcache にプリロードしてから、memcache から読み取ろうとしました。検索ごとに SQL Server への呼び出しを回避しようとしていました。

    これには多くの時間がかかります。ユーザーがアイテムを検索するたびに、memcache から 100,000 レコードを取得して検索を実行しています。これには、直接の SQL 検索よりもほぼ 2 ~ 3 倍の時間がかかります。

  2. SQL Server テーブルで直接検索を試みましたが、結果を一度に 50 レコードのみに制限しました (上位 50 を使用)。

    これは問題ないように見えますが、求めているパフォーマンスにはまだほど遠い状態です

可能な解決策と記事/コードへのリンクを聞きたいです。

前もって感謝します

4

3 に答える 3

0

いくつかの仮定などに依存するため、機能する可能性のある奇妙な代替手段です。申し訳ありませんが、完全に説明されていませんが、入力するのが難しいiPadを使用しています。(そして、はい、このソリューションは、高 txn 商用システムで使用されています)

これは、

  1. クエリが IO ではなく CPU に制約されていること
  2. その itemName は長すぎず、すべての文字と数字を保持できます
  3. 全体として、その検索ワードには十分な選択文字が含まれており、非常に一般的な文字だけではありません
  4. 選択述語は %like% によって制限されています

基本的な考え方は、クエリを拡張して、オプティマイザーがどの行に類似スキャンが必要かを認識できるようにすることです。

ステップ 1. テーブルをセットアップする

文字/数字ごとに追加の 26 または 36 列を作成します。私が実際にこれを行ったとき、それは常に別のテーブルでしたが、ソーステーブルに配置しても、100k のような小さなボリュームの場合は問題ありません。列 trig_a、trig_b などを呼び出しましょう。

挿入/編集/削除ごとにトリガーを作成し、trig_a フィールドに「a」が含まれている場合は 1 または 0 を入力します。26/36 列すべてに対してこれを行います。これを行うトリガーは複雑ですが、可能です (少なくとも Oracle を使用する場合)。行き詰まったら、SO'ers が作成するか、私が掘り出すことができると確信しています。

この時点で、フィールドに文字/数字などが含まれているかどうかを示す一連の列があります。

ステップ 2. クエリの支援

この追加情報により、私たちはオプティマイザーを支援する立場にあります. 以下をクエリに追加します

Select ... Where .... And
 ((trig_a > 0) or (searchword not like '%a%')) and
 ((trig_b > 0) or (searchword not like '%b%')) and
   ... Repeat for all columns monitored...

オプティマイザーが動作する場合、(うまくいけば) 低コスト フィールド >0 述語を使用して、評価される類似述語を減らすことができます。

ノート。

  1. オプティマイザに trig_? を強制的にスキャンさせる必要がある場合があります。フィールドが最初
  2. インデックスは trig_? で役立ちます。フィールド、特にソース テーブルにある場合
  3. 大文字/小文字の処理方法を示していません。これを処理することを忘れないでください
  4. ほんの数文字を入力するだけで十分であることに気付くかもしれません。
  5. この手法は、like を使用するたびにパフォーマンスが向上するわけではないため、like を使用するすべての場所で汎用的な手法ではありません。
于 2013-08-02T20:48:19.080 に答える