4

約 6 ~ 7 個の結合テーブルと、WHERE のベース テーブルの 6 列に対する FREETEXT() 述語を含むクエリがあります。

現在、このクエリは昨年 (2 秒未満で) 正常に機能し、実質的に変更されていません (古いバージョンを試してみましたが、問題は解決しません)。

そのため、今日、突然、同じクエリに約 1 ~ 1.5 分かかりました。

SQL Server 2005 で実行計画を確認した後、そのテーブルの FULLTEXT インデックスを再構築し、FULLTEXT インデックスを再編成し、インデックスを最初から作成し、SQL Server サービスを再起動し、サーバー全体を再起動しました。

LIKEこれを理解するまで、代わりに使用するクエリを一時的に切り替えました(現在は約6秒かかります)。

クエリ パフォーマンス アナライザーでクエリを見ると、「FREETEXT」クエリと「LIKE」クエリを比較すると、前者の読み取り数は 350 倍 (4921261 対 13943)、20 倍 (38937 対 1938) です。後者のCPU使用率。

したがって、実際には「FREETEXT」述語が非常に遅くなります。

理由が何であるかについて誰かが何か考えを持っていますか? または、さらにテストを行うことができますか?

[編集]

さて、実行計画を取得するためにクエリを再度実行したところ、変更を加えることなく、再び 2 ~ 5 秒かかりましたが、昨日の問題はまだ存在していました。先週の木曜日に最初に問題をテストしたときに、データベースにアクセスするすべてのアプリケーションを停止したので、それは外的要因によるものではなく、他の負荷によるものではありませんでした.

まあ、実行計画はまだ含めますが、すべてが再び機能するようになったので、あまり役に立たないかもしれません...そして、これは変更できないレガシーデータベースへの巨大なクエリです(つまり、データを正規化したり、いくつかの不要な中間テーブルを取り除きます)

クエリ プラン

ここに完全なクエリがあります

それが正確に何をするのかを説明しなければならないかもしれません。基本的に、求人広告の検索結果を取得します。ここには、プレミアム広告と通常広告の 2 種類の広告があります。結果は 1 ページあたり 25 の結果にページ分割され、十分な数がある場合は、10 のプレミアム結果が一番上に、15 の通常の結果がその後に表示されます。

そのため、必要な数のプレミアム/ノーマル クエリを選択する 2 つの内部クエリがあり (たとえば、10 ページでは、上位 100 のプレミアム クエリと上位 150 の通常クエリをフェッチします)、これら 2 つのクエリは、row_number() コマンドといくつかの数学でインターリーブされます。 . 次に、組み合わせが行番号順に並べられ、クエリが返されます。別の場所で、現在のページに必要な 25 個の広告を取得するために使用されます。

ああ、このクエリ全体は巨大なレガシーColdfusionファイルで構築されており、うまく機能しているので、これまでのところ大部分を触れたり変更したりすることはできませんでした...実行中のシステムなどには触れないでください;)変更などの小さなものだけです中央の where 節のビット。

このファイルは、基本的に同じことを行う他のクエリも生成しますが、プレミアム/非プレミアムの区別と、このクエリの他の多くのバリエーションがないため、それらの1つを変更すると他のクエリがどのように変更されるかはわかりません.. .

問題が再び表面化していないので、マーティンに賞金を与えました。彼はこれまでで最も役に立ち、賞金が不必要に期限切れになりたくなかったからです。他の皆さんの努力に感謝します。また同じことが起こったら、あなたの提案を試してみます :)

4

2 に答える 2

1

この問題は、フル テキスト クエリによって返される結果の数のカーディナリティの見積もりが不十分であるために発生する可能性があり、JOIN 操作の戦略が不適切になる可能性があります。

パフォーマンスを 2 つのステップに分けた場合、どのようにパフォーマンスを見つけますか?

一時テーブルまたはテーブル変数にフル テキスト クエリの結果を入力する 1 つの新しいステップと、代わりに一時テーブルを参照するように既存のクエリを変更する 2 つ目のステップ。

(注: OPTION(RECOMPILE)(A) 多くの結果を返すフリー テキスト検索用語 (B) ほんの一握りの結果しか返さないクエリ プランを調べながら、この JOIN を使用して、または使用せずに試してみることをお勧めします。)

編集問題のあるクエリがない場合に正確に明確にすることは困難ですが、私が意味するのは、代わりに

SELECT <col-list>
FROM --Some 6 table Join
WHERE FREETEXT(...);

これはどのように機能しますか?

DECLARE @Table TABLE
(
<pk-col-list>
)
INSERT INTO @Table
SELECT PK
FROM YourTable
WHERE FREETEXT(...)

SELECT <col-list>
FROM --Some 6 table Join including onto @Table
OPTION(RECOMPILE)
于 2010-05-31T15:36:07.803 に答える
0

通常、この問題が発生するのは、テーブルの断片化と問題のインデックスの古い統計が原因です。

次回は、再構築/再インデックスの後にsp_updatestatsを実行してみてください。

詳細については、統計を使用してクエリのパフォーマンスを向上させるを参照してください。

于 2010-06-02T22:05:38.837 に答える