Asp.net Webサイトで、データベースに対して実行される挿入、更新、削除のクエリが多数あります。
数日前に、1つのテーブルの2つの列にフルテキストインデックスを作成しました。その後、Webサイトがそのテーブルに対して更新クエリを実行すると、SQL Serverプロセスのメモリとディスクの使用量が急激に増加し、更新が遅くなることがわかりました。クエリは、フルテキストインデックスを作成する前に、パフォーマンスの問題なしに実行されました。
以前は非常に単純だった更新クエリが複雑になっていることにも気付きました。これは、実行プランに全文インデックスの更新などがあるためです。これは、フルテキストを有効にすると複雑になった新しい実行プランの一部です。
サイトのコンテンツを更新する数時間で、5000の更新クエリを実行しました。フルテキストインデックス処理は、各行で毎回行われると思います。
行の更新の開始時に全文スキャンを無効にしてから、再度有効にする必要がありますか( この関連する質問 のように)?
SQL Serverに5分間全文索引付けを停止してから、新しいデータの索引付けを開始するように指示できますか?
より良い代替案はありますか? SQL Server 2012を使用しています。
私の場合、非効率的なUPDATEステートメントを変更する必要がありました。
前:
UPDATE Customer
SET Rating = 'Not Rated'
WHERE ...
後:
UPDATE Customer
SET Rating = 'Not Rated'
WHERE ...
AND Rating <> 'Not Rated' -- THIS LINE WAS INSERTED
これにより、パフォーマンスが4分から5秒に改善されました。問題は、割り当てたい値がすでにそれらの行にあったとしても、すべての行を更新していたことです。
停止する(無効にする)と、インデックスを使用するクエリでインデックスを使用できなくなります。
ただし、変更追跡を手動に設定できます。
--disable automatic change tracking
ALTER FULLTEXT INDEX ON schema.table SET CHANGE_TRACKING MANUAL
GO
--run the update statement here
--re-enable automatical change tracking after updating it to reflect the recent changes
ALTER FULLTEXT INDEX schema.table START UPDATE POPULATION
GO
ALTER FULLTEXT INDEX ON schema.table SET CHANGE_TRACKING AUTO
GO
次のクエリで現在の値を確認できます。
SELECT TOP(10) change_tracking_state_desc, *
FROM sys.fulltext_indexes
WHERE object_name(object_id) = '...';
有効なオプションは次のとおりです:SET CHANGE_TRACKING {MANUAL | AUTO | OFF}
フルテキストインデックスの対象となるテーブル列に加えられた変更(更新、削除、または挿入)がSQL Serverによってフルテキストインデックスに伝達されるかどうかを指定します。 WRITETEXT
およびUPDATETEXT
を介したデータ変更は、フルテキストインデックスに反映されず、変更追跡で取得されません。
ALTER FULLTEXT INDEX(Transact-SQL) については、Microsoftのドキュメントを参照してください。