フルテキストインデックスを維持するために考慮すべきガイドラインは何ですか?
フルテキストカタログを再構築または再編成する必要がありますか( [〜#〜] bol [〜#〜] を参照)?合理的なメンテナンスケイデンスとは何ですか?メンテナンスが必要な時期を判断するために使用できるヒューリスティック(10%および30%の断片化しきい値と同様)は?
(以下のすべては、質問について詳しく説明し、私がこれまでに考えたことを示す追加情報です。)
追加情報:私の最初の研究
Bツリーインデックスのメンテナンスに関するリソースはたくさんあります(例: この質問 、 Ola Hallengrenのスクリプト 、および他のサイトの件名に関する多数のブログ投稿)。ただし、これらのリソースのいずれも、フルテキストインデックスを維持するための推奨事項やスクリプトを提供していないことがわかりました。
ベーステーブルのbツリーインデックスをデフラグしてからフルテキストカタログでREORGANIZEを実行するとパフォーマンスが向上する可能性があるが、それ以上の具体的な推奨事項には触れないことを言及している Microsoftのドキュメント があります。 。
私も この質問 を見つけましたが、これは主に変更追跡(基になるテーブルへのデータ更新がフルテキストインデックスに伝達される方法)に焦点を当てており、効率を最大化できる定期的にスケジュールされたメンテナンスの種類ではありませんインデックスの。
追加情報:基本的なパフォーマンステスト
これ SQL Fiddle には、AUTO
変更追跡を使用してフルテキストインデックスを作成し、テーブルのデータが変更されたときにインデックスのサイズとクエリパフォーマンスの両方を調べるために使用できるコードが含まれています。 (フィドルで人工的に製造されたデータとは対照的に)本番データのコピーでスクリプトのロジックを実行すると、各データ変更ステップ後に表示される結果の概要は次のとおりです。
このスクリプトの更新ステートメントはかなり工夫されていますが、このデータは、定期的なメンテナンスによって得られることがたくさんあることを示しているようです。
追加情報:初期のアイデア
毎晩または毎週のタスクを作成することを考えています。このタスクは、REBUILDまたはREORGANIZEを実行できるようです。
フルテキストインデックスはかなり大きい(数千または数億行)場合があるため、カタログ内のインデックスが十分に断片化され、REBUILD/REORGANIZEが必要となる場合を検出できるようにしたいと考えています。どのヒューリスティックがそのために意味をなすかについては、少し不明確です。
オンラインで適切なリソースを見つけることができなかったため、さらに実践的な調査を行い、その調査に基づいて実装している結果のフルテキストメンテナンス計画を投稿することは有益だと思いました。
メンテナンスが必要な時期を判断するためのヒューリスティック
私たちの主な目標は、基になるテーブルでデータが進化しても一貫したフルテキストクエリのパフォーマンスを維持することです。ただし、さまざまな理由により、各データベースに対して代表的なフルテキストクエリのスイートを毎晩起動し、それらのクエリのパフォーマンスを使用してメンテナンスが必要な時期を判断することは困難です。そのため、非常に迅速に計算でき、全文索引の保守が保証される可能性があることを示すヒューリスティックとして使用できる経験則を作成しようとしていました。
この調査の過程で、システムカタログは、特定のフルテキストインデックスがフラグメントに分割される方法に関する多くの情報を提供することがわかりました。ただし、計算された公式の「フラグメンテーション%」はありません(b-treeインデックスでは sys.dm_db_index_physical_stats を使用するため)。全文フラグメント情報に基づいて、独自の「全文フラグメント%」を計算することにしました。次に、開発サーバーを使用して、本番データの1,000万行のコピーに対して一度に100〜25,000行のランダムな更新を繰り返し行い、フルテキストの断片化を記録し、CONTAINSTABLE
。
上のグラフと下のグラフに示されているように、結果は非常にわかりやすく、作成した断片化指標が観察されたパフォーマンスと非常に高い相関があることを示しています。これは本番環境での定性的観測とも結びついているため、フルテキストインデックスをいつメンテナンスする必要があるかを判断するためのヒューリスティックとして断片化%を使用しても問題ありません。
保守計画
次のコードを使用して、各フルテキストインデックスの断片化%を計算することにしました。少なくとも10%の断片化を伴う重要なサイズのフルテキストインデックスは、オーバーナイトメンテナンスによって再構築されるようにフラグが立てられます。
-- Compute fragmentation information for all full-text indexes on the database
SELECT c.fulltext_catalog_id, c.name AS fulltext_catalog_name, i.change_tracking_state,
i.object_id, OBJECT_SCHEMA_NAME(i.object_id) + '.' + OBJECT_NAME(i.object_id) AS object_name,
f.num_fragments, f.fulltext_mb, f.largest_fragment_mb,
100.0 * (f.fulltext_mb - f.largest_fragment_mb) / NULLIF(f.fulltext_mb, 0) AS fulltext_fragmentation_in_percent
INTO #fulltextFragmentationDetails
FROM sys.fulltext_catalogs c
JOIN sys.fulltext_indexes i
ON i.fulltext_catalog_id = c.fulltext_catalog_id
JOIN (
-- Compute fragment data for each table with a full-text index
SELECT table_id,
COUNT(*) AS num_fragments,
CONVERT(DECIMAL(9,2), SUM(data_size/(1024.*1024.))) AS fulltext_mb,
CONVERT(DECIMAL(9,2), MAX(data_size/(1024.*1024.))) AS largest_fragment_mb
FROM sys.fulltext_index_fragments
GROUP BY table_id
) f
ON f.table_id = i.object_id
-- Apply a basic heuristic to determine any full-text indexes that are "too fragmented"
-- We have chosen the 10% threshold based on performance benchmarking on our own data
-- Our over-night maintenance will then drop and re-create any such indexes
SELECT *
FROM #fulltextFragmentationDetails
WHERE fulltext_fragmentation_in_percent >= 10
AND fulltext_mb >= 1 -- No need to bother with indexes of trivial size
これらのクエリは次のような結果を生成します。この場合、行1、6、および9は、フルテキストインデックスが1MBを超え、少なくとも10%が断片化されているため、最適化されていないため断片化されているとマークされます。
メンテナンスケイデンス
私たちはすでに毎晩のメンテナンスウィンドウを持っており、断片化の計算は非常に安価に計算できます。したがって、このチェックを毎晩実行し、10%の断片化のしきい値に基づいて、必要なときにフルテキストインデックスを実際に再構築するというよりコストの高い操作のみを実行します。
REBUILD対REORGANIZE対DROP/CREATE
SQL ServerはREBUILD
およびREORGANIZE
オプションを提供しますが、それらは完全なフルテキストカタログ(フルテキストインデックスをいくつでも含むことができる)でのみ使用できます。従来の理由により、すべてのフルテキストインデックスを含む単一のフルテキストカタログがあります。したがって、(DROP FULLTEXT INDEX
)を作成してから再作成します(CREATE FULLTEXT INDEX
)代わりに、個々のフルテキストインデックスレベルで。
フルテキストインデックスを論理的な方法で個別のカタログに分割し、代わりにREBUILD
を実行する方が理想的ですが、当面はドロップ/作成ソリューションが機能します。