2

結果を返すのが非常に遅い非常に複雑なクエリがあります。犯人が全文検索に関係する WHERE 句の一部であることは最初から明らかでした。だから私はそれを分離してテストしました。このテストの結果、それがいつ発生するかを突き止めることができましたが、これまでのところ、それを修正する方法を理解することができませんでした. 問題は次のとおりです。

ユーザーの目的に基づいて、1 つ、2 つ、または 3 つのフルテキスト インデックス付き列をフィルター処理する必要があります。CONTAINS 述語内の列リストを変数として指定できないように思われるため、次に考えられる最善の方法は、次のような標準的なブール論理を使用することです。

(((@SearchInName = 0 AND @SearchInShortDescr = 0 AND @SearchInHTMLDescr = 0) OR @SearchExpression = '""')
OR (@SearchInName = 1 AND @SearchInShortDescr = 0 AND @SearchInHTMLDescr = 0 AND CONTAINS(ProductName, @SearchExpression))
OR (@SearchInName = 0 AND @SearchInShortDescr = 1 AND @SearchInHTMLDescr = 0 AND CONTAINS(ProductShortDescr, @SearchExpression))
OR (@SearchInName = 0 AND @SearchInShortDescr = 0 AND @SearchInHTMLDescr = 1 AND CONTAINS(ProductDescrHTML, @SearchExpression))
OR (@SearchInName = 1 AND @SearchInShortDescr = 1 AND @SearchInHTMLDescr = 0 AND CONTAINS((ProductName, ProductShortDescr), @SearchExpression))
OR (@SearchInName = 1 AND @SearchInShortDescr = 0 AND @SearchInHTMLDescr = 1 AND CONTAINS((ProductName, ProductDescrHTML), @SearchExpression))
OR (@SearchInName = 0 AND @SearchInShortDescr = 1 AND @SearchInHTMLDescr = 1 AND CONTAINS((ProductShortDescr, ProductDescrHTML), @SearchExpression))
OR (@SearchInName = 1 AND @SearchInShortDescr = 1 AND @SearchInHTMLDescr = 1 AND CONTAINS((ProductName, ProductShortDescr, ProductDescrHTML), @SearchExpression))

実際の有効な条件が最後の OR セクションと一致する限り、それは問題なく、期待どおり (高速) に機能します。上記の例では、@SearchInName = 1 AND @SearchInShortDescr = 1 AND @SearchInHTMLDescr = 1 の場合になります (ユーザーは 3 つの列すべてを検索したいと考えています)。他の条件も、このコード ブロック内の最後に配置すると、すぐに戻ります。ただし、実際の有効な条件が最後よりも高くなるとすぐに、それに続くすべての CONTAINS ステートメントも実行されるように見えます (ただし、必ずしも結果に含まれているとは限りませんが、これは正しいことです)。これにより、実行時間が 1 秒未満から 6 秒に短縮されます。有効なステートメントがどれだけ高いか、したがって他の CONTAINS 述語がいくつ続くかに応じて、秒以上かかります。

実行の順序が実際のコードによって常に与えられるとは限らず、SQL の最適化後に一部の短絡が設計どおりに機能しない可能性があることを理解しています。これはこのケースのようです。通常、CASE ステートメントを使用して順序を確保することをお勧めしますが、残念ながら CONTAINS ステートメントは CASE ステートメント内で適切に機能していないようです。

ですから、なぜそれが起こっているのか(SQLの最適化)はおそらくある程度知っていると思いますが、実際にこれを修正する方法を理解することはできません. 誰でも助けることができますか?

4

1 に答える 1