11

フル テキスト カタログを作成したテーブルがあります。テーブルには 6000 を少し超える行があります。インデックスに 2 つの列を追加しました。1 つ目はある種の一意の識別子と見なすことができ、2 つ目はそのアイテムのコンテンツと見なすことができます (私のテーブルには、フル テキスト カタログの一部ではない11 の他の列があります)。いくつかの行の例を次に示します。

TABLE: data_variables
ROW    unique_id    label
1      A100d1       Personal preference of online shopping sites
2      A100d2       Shopping behaviors for adults in household

UNIQUE IDフロント エンドの Web アプリケーションには、ユーザーが入力できるテキスト ボックスがあり、またはのLABEL列で検索している用語に一致するアイテムのリストを取得できます。したがって、たとえば、ユーザーがshoorと入力した場合a100、リストには上記の両方の行が入力されます。入力したbehav場合、リストには上の行 2 のみが表示されます。

これは、各 で Ajax リクエストを介して行われますkeyup。PHP は、次のような SQL サーバーでストアド プロシージャを呼び出します。

SELECT TOP 50 dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         (CONTAINS((dv.unique_id, dv.label), @search))

(@searchは、ストアド プロシージャに渡されるユーザーからのテキストです。)

TOP 50特にクエリで使用していない場合は、これがかなり遅くなることに気付きました。

私が探しているのは、SQL Server 上で直接、またはフルテキスト インデックス作成のアイデアを放棄し、jQuery を使用してクライアント側で検索可能な項目の配列を検索することにより、これを高速化する方法です。私は jQuery AutoComplete のものと AutoComplete 用の他の jQuery プラグインを少し調べましたが、まだ何もモックアップしようとはしていません。それが私の次のステップになりますが、最初にここで確認して、どのようなアドバイスが得られるかを確認したいと思いました.

前もって感謝します。

4

5 に答える 5

6

線形インデックス(左から右)を使用していて、のようなクエリを実行している場合を除いて、LIKEには反対することをお勧めしますLIKE 'work%'。通常のインデックスのようなことをしている場合はLIKE '%word%'、役に立ちません。段落内の単語を検索する場合は、通常、フルテキストインデックスを使用します。

多くのデータがある場合、通常、データベースに組み込まれているフルテキストエンジンはあまり盗まれません。最高のパフォーマンスを得るには、通常、フルテキスト用に特別に構築された外部ソリューションを使用する必要があります。

いくつか例を挙げると、いくつかのオプションはSphinxSolrelasticsearchです。これらのオプションのいずれかが他のオプションよりも優れているとは言えません。考慮すべき賛否両論が確かにあります:

  • どんなデータがありますか?
  • これらのソリューションにはどのような言語サポートがありますか?
  • これらのソリューションはどのデータベースエンジンをサポートしていますか?

できる最善のことは、これらのソリューションを既存のデータに対してベンチマークすることです。個々のコンポーネントをすべてテストする(単体テスト)と、実際の問題を特定し、適切な解決策を見つけるのに役立ちます。

于 2013-03-08T18:50:37.670 に答える
6

6000行しかないという事実に基づいて、いくつかの提案があるため、データベースはこれを生きたまま食べる必要があります。

A. 念のため、Like 演算子を使用してみてください。それも期待していませんが、試すのはかなり簡単です。これらの小さなボリュームを考えると、これが遅いことを検出するために、ここで全体的に何か他のことが起こっています。

B. 事前にクエリをキャッシュできますか? 6000 行の場合、2 文字のクエリの組み合わせはおそらく 36*36 しかないため、事実上メモリを消費せず、データベースの作業を節約できます。

C. 選択をクライアントに移動することは良い考えです。これは、6000 行の全体的な大きさと、個々のルックアップのネットワーク遅延に依存します。

D. b と c を組み合わせると、非常に優れたパフォーマンスが得られると思いますが、多少のコーディング作業が必要です。サーバーがすべての単一文字結果のリストをキャッシュに維持し、クライアントが最初のキーストロークの後に文字キャッシュ セットをダウンロードする場合、クライアントはすべての行のサブセットを持つ可能性がありますが、追加のキーストロークのためにネットワーク IO を追加する必要はありません。

于 2013-03-02T19:57:54.703 に答える
5

私は同じ問題を抱えていて、LIKEソリューションを選びました。また、or演算子に負担がかかりすぎて、クエリをすべてユニオンで2つの選択に分割することもわかりました(最速で、私のシナリオでは、インデックス列とデータで同じテキストを見つけることができませんでした)。

あなたは次のようになります

SELECT TOP 50 from (
select dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         dv.unique_id like '%'+@search+'%'
UNION ALL
select dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         dv.label like '%'+@search+'%' 
)

おー!!そして、WebではなくSQLServerでパフォーマンスをテストしてください。

于 2013-03-07T10:55:48.777 に答える
2

データ量を増やす予定がある場合は、全文検索に逆索引を使用するのが最善の方法です。

現時点で最高の全文検索エンジンであるApache Solrを見てください。

定期的にデータベース データのインデックスを作成し、solr を検索エンジンとして使用するだけで、シンプルな ajax API を提供し、フロントエンドから直接クエリを実行できます。

于 2013-03-06T16:03:13.170 に答える
0

本当にパフォーマンスが必要な場合は、以下を参照してください。FTS3とFTS4 ...

中略...別のフォーラムから...

たとえば、"Enron E-Mail Dataset" 内の 517430 のドキュメントのそれぞれが、FTS テーブルと、次の SQL スクリプトを使用して作成された通常の SQLite テーブルの両方に挿入されるとします。

コード: CREATE VIRTUAL TABLE enrondata1 USING fts3(content TEXT); /* FTS3 テーブル/ CREATE TABLE enrondata2(content TEXT); /通常のテーブル */ 次に、以下の 2 つのクエリのいずれかを実行して、「linux」という単語 (351) を含むデータベース内のドキュメントの数を見つけることができます。1 つのデスクトップ PC ハードウェア構成を使用すると、FTS3 テーブルのクエリは約 0.03 秒で返されますが、通常のテーブルのクエリは 22.5 秒です。

見る...

http://www.sqlite.org/fts3.html

于 2013-03-09T15:10:05.787 に答える