2017-02-15 5 views
1

非常に大きな/人気のサイトであるASP MVCサイトを運用環境に展開しており、かなりのトラフィックが発生します。SQL Server R2 2008の全文検索「待ち時間のタイムアウト」がランダムに発生する

私たちは全文検索を使用して検索施設を運転しています。

私たちのELMAHログには、非常にランダムなエラーが表示されます。「待機操作がタイムアウトしました」。このエラーが発生した場合、多くのお客様に同じようなことが起こっているようです。このエラーの4つまたは5つのインスタンスがすべて同じタイムスタンプ内に記録されます。孤立して起こることは決してありません。

基本的に私たちのカタログページには、私たちが実行する5〜6つの質問があります(例えば、「すべてのサブカテゴリを取得する」、「すべてのメーカーを取得する」、「最小/最大価格帯を取得する」、私はそれが例外を引き起こすこれらのメソッドの1つになるスタック・トラックを見て見ることができます。

しかし、一般的なことは、ユーザーのフィルタオプションを使用して各クエリに適用して関連情報を表示することです。

検索用語が存在する場合、これは失敗する(ごくまれに)ようです。たとえば、顧客が検索語句なしでカタログページを閲覧したときに、他のタイムアウトの問題は見られませんでした。

誰でも潜在的なデッドロックが発生する可能性のある方向を指摘できますか?当社の全文索引は、製品表からデータを引き出すビュー上にあります。これは株式情報などで何度も更新されますが、ビューが引き込む列は頻繁にデータを変更しません。 ランダムなので実際にどこにあるのかを正確に突き止めるのは難しいです。以前は例外が発生していたURLに移動したときに、ページが本当に素早く読み込まれます(検索結果がある程度キャッシュされているかのように)。

ビット詳細: 54612ビューの行(2列 - プロダクトID /検索テキスト)、フルテキストが索引付けされる 検索テキスト列は95文字で最大行を有するので、データの膨大な量ではありません。ほとんどの場合、カタログページはレンダリングに約600msかかるが、これらのクエリは通常約20〜30msかかる。しかし、時にはこれが大量に発生する - 私は、各クエリを実行するのに約6秒かかり、6つのうちの1つがタイムアウトし、非常にランダムなスパイクが発生するトレースを見た。私は本当にこの減速を自分で経験したことはありませんが、私はあまり頻繁にサイトを閲覧しませんが、頻繁な減速を示す新しい遺跡取引(およびエラーログ)があります。&タイムアウト。

SELECT p.Id AS ProductId, Colour + ' ' + Size ' ' + m.Name + ' ' + Categories AS FullSearch 
FROM Product 
INNER JOIN Manufacturer m ON m.Id = p.ManufacturerId 
WHERE Deleted = 0 

当社の製品表には、性能も目的のためにいくつかのデ正規化されたデータが含まれています。私たちは

@Search = '("some*" AND "search*" AND "terms*")' 

SELECT TOP ? * FROM (SELECT p.Score, [columns], [Rank] as SearchRank, ROW_NUMBER() OVER 
(ORDER BY p.Score * [Rank] DESC, p.Id DESC) AS row_number 
FROM Product p 
INNER JOIN Manufacturer AS m ON p.ManufacturerId = m.Id 
INNER JOIN ProductCategory pcm ON p.Id = pcm.ProductId 
INNER JOIN CONTAINSTABLE(vw_SearchProducts, FullSearch, @Search) AS FTS ON p.Id = FTS.[KEY] 
WHERE p.Deleted = ? AND pcm.CategoryId = @CategoryId) p WHERE p.row_number > ? ORDER BY p.Score * SearchRank DESC, p.Id DESC 

を使用してクエリを実行していると我々の見解は、FTSキーとして商品コードでは、そのようなように見えます

。 カタログページの6つの主なクエリは、すべて上記と似ていますが、フィルタリング/検索基準に一致する製品のデータを別々に取得するだけです。

私たちはすぐにSQL Server 2016にアップグレードします。これは、それがもっとうまくいくかどうかは不明です。

乾杯

答えて

1

あなたはSQL Server Profilerを開始し、数時間または日のために実行し、それを残すことができる、そしてあなたが再びログにタイムアウトを見たときに、その頃SQLプロファイラで記録されたクエリを見つけ、持続時間をチェック/読み込み/列の値を書き込みます。

このようにして、タイムアウトの原因となった特定のパラメータリストを持つEXACTストアドプロシージャ/ステートメントを特定できるようになります。そうであれば、SSMSと実行計画タブを使用してさらにデバッグすることができます。

もちろん、FTSカタログがあまりにも頻繁に再構築されている可能性があります。これはトラップすることもできますが、正確なタイムアウトの瞬間をキャッチし、FTSカタログステータスが再構築されているかどうかを確認する必要があります。

SQL 2012-2016にアップグレードすると、FTS、特にFTSインデックスの更新速度が改善されるはずです。 MSは、そのような同時FTSインデックス更新の最大10倍のスピードアップを請求しています。この回答はAre there any Sql Server Full-Text Search (FTS) performance improvements since version 2008 R2?です。

データの記録はそれほど多くはありません。数百万のレコードに対してSQL Server FTSを実行し、タイムアウトは発生しません。ほとんどの結果は10秒未満ですが、この遅延はFTSでは発生しません。実際のFTSブロックは非常に速く実行されます。追加のJOINとフィルタは、最初のFTS結果に適用して追加の遅延を招く必要があります。

もう一つのアイデアは、あなたのVIEWは多分悪い実行計画は、SQL Serverによってキャッシュされませんどのように設計または我々が実際VIEWコード、特にJOIN/WHERE部分を参照してくださいする必要があり、これを確認するなど、それ自体に参加しています。

+0

こんにちはandrews私はサンプルクエリと私たちのビューがどのように見えるかを追加しました。プロファイラーでうれしい私は、FTSの人口についてどのようなタイミングが報告されているかを見極めるために掘り下げてきました。数ミリ秒からちょうど1秒以上の時間が見られました。私は'16アップグレードがすぐに来ると思う - うまくいけば、それは物事を助けるはずだ、私は最近、これらの頻度で大きなジャンプを気づいた。 –

+0

@StevenSproat投票に感謝します。 SQLプロファイラでINSERT呼び出しを監視する場合、それらはFTSインデックス挿入ではなく、基になるテーブルINSERTSであることに注意してください。 FTSは基本表を監視し、FTS索引付けされたデータが変更されると、実際のFTS索引の再構築を開始し、プロファイラでその索引が表示されません。代わりに、SSMSを介してFTSインデックスプロパティを選択するか、この回答のようなクエリを実行すると表示されます:http://stackoverflow.com/a/2727952/5857386 – andrews

+0

手つかずの場合、FTSインデックスの人口状況は 'IDLE'ですが、再構築中はSSMSはそのステータスを' Populating'として報告します。そのため、FTSのインデックスステータスを監視して、再構築が頻繁に行われているかどうかを確認してください。 – andrews

関連する問題