web-dev-qa-db-ja.com

全文索引が遅れているのはなぜですか?

テーブルにフルテキストインデックスを設定しています。テーブルの負荷はかなり一定で、毎日約5万回の挿入と約35万回の削除が行われ、挿入間のギャップはかなり短い(最大5分)。
インデックスは自動変更追跡用に構成されており、通常、挿入から数秒以内にすべてのドキュメントを処理できます。ただし、昨日の監視では、インデックスが4時間以上更新されなかったことが警告されました。
そのアラートを受け取った後、私は次のことを確認しました:

  • フルテキストログに新しいエントリは表示されませんでした。最後のエントリは情報提供でした-全文自動入力が完了しました。
  • インデックス作成のステータス(sys.dm_fts_index_populationによって報告される)が「処理を停止しました」でスタックしました。
  • コマンド「FT BATCH CMPLETE」を実行する単一のセッションが、CPUコア全体を使用していました。そのセッションのlast_request_start_timeは、フルテキストログの最後のエントリから数秒以内でした。それ以外は、CPUはアイドル状態でした。
  • (sys.fulltext_index_fragmentsによって報告されるように)2つの(30のうちの)フラグメントはステータス6 /マージ入力に使用され、クエリの準備ができています。これらのフラグメントのサイズは、それぞれ60GB近くでした。

およそ10時間後、インデックス作成が停止したのと同じくらい不思議なことに再開しました。

マージのために索引付けが一時停止されたと私は思うのでしょうか?そうでない場合、より良い診断を得るために他に何をチェックできますか?

この問題は、異なるサーバーで月に約2回発生します。私の知る限りでは、インデックスはスケジュールに従って再編成または再構築されていません。インデックス作成の一時停止を完全に回避するか、メンテナンスダウンタイム中に一時停止をスケジュールできるようにするソリューションを探しています。サーバーはSQL Server 2012 Enterpriseです。

4
Daniel Jelinski

どうやらMS SQL Server 2012では、複数のインデックススレッドを並行して実行することはできません。インデックススレッドは、ドキュメントの現在のバッチのインデックス作成が完了した後にマージを実行する可能性があるため、インデックス作成は一時停止します。

手動の変更追跡は役に立ちません。別々のセッションで実行される複数のUPDATE POPULATIONコマンドも、マージの実行中に互いにブロックします。

たとえばインデックスを再編成することにより、マージされるフラグメントのサイズを制御することができます。再編成操作では、すべてのインデックスフラグメントが1つにマージされます。 reorganizeによって作成されたフラグメントは大きすぎてマージできないため、新しいフラグメントはかなり小さいため、マージは高速です。

私たちの場合、新しいインデックスフラグメントが数ギガバイトに達するまでに数週間かかり、毎週の再編成はオプションです。

1
Daniel Jelinski

何が起こっているのかからより多くの情報を得るために試みることができるいくつかのクエリがあるようです。 Stackoverflow から取得した以下のクエリは、FULLTEXTCATALOGPROPERTYを利用しています。

DECLARE @CatalogName VARCHAR(MAX)
SET     @CatalogName = 'FTS_Demo_Catalog'

SELECT
    DATEADD(ss, FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateCompletionAge'), '1/1/1990') AS LastPopulated
    ,(SELECT CASE FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateStatus')
        WHEN 0 THEN 'Idle'
        WHEN 1 THEN 'Full Population In Progress'
        WHEN 2 THEN 'Paused'
        WHEN 3 THEN 'Throttled'
        WHEN 4 THEN 'Recovering'
        WHEN 5 THEN 'Shutdown'
        WHEN 6 THEN 'Incremental Population In Progress'
        WHEN 7 THEN 'Building Index'
        WHEN 8 THEN 'Disk Full.  Paused'
        WHEN 9 THEN 'Change Tracking' END) AS PopulateStatus
FROM sys.fulltext_catalogs AS cat

ただし、この article では、Microsoftは次のように述べています。

通常は、対応するPopulateStatusプロパティをOBJECTPROPERTYEXシステム関数のTableFullTextPopulateStatusテーブルレベルで確認する方が適切です。これとOBJECTPROPERTYEXの他の新しいフルテキストプロパティは、フルテキストインデックステーブルに関するより詳細な情報を提供します。

これには、次のスクリプトを使用します。

DECLARE @TableId VARCHAR(MAX)
SET @TableId = OBJECT_ID('gGastroversion')

Select CASE OBJECTPROPERTYEX ( @TableId , 'TableFullTextPopulateStatus' )
            WHEN 0 THEN 'Idle'
            WHEN 1 THEN 'Full Population In Progress'
            WHEN 2 THEN 'Full population is in progress.'
            WHEN 3 THEN 'Propagation of tracked changes is in progress.'
            WHEN 4 THEN 'Background update index is in progress, such as autochange tracking.'
            WHEN 5 THEN 'Full-text indexing is throttled or paused.'
            WHEN 6 THEN 'An error has occurred. Examine the crawl log for details'
        END

結果として6番の場合は、クロールログを確認するよう指示されます。この情報のトラブルシューティングは here で見つけることができます。

1
James Rhoat