Руководство по ведению полнотекстового индекса

29

Какие рекомендации следует учитывать при ведении полнотекстовых индексов?

Должен ли я перестроить или переорганизовать полнотекстовый каталог (см. BOL )? Что такое разумная частота обслуживания? Какие эвристики (аналогичные порогам фрагментации 10% и 30%) можно использовать для определения необходимости технического обслуживания?

(Все, что ниже, - просто дополнительная информация, уточняющая вопрос и показывающая, о чем я думал до сих пор.)



Дополнительная информация: мое первоначальное исследование

Существует множество ресурсов по ведению индекса b-дерева (например, этот вопрос , сценарии Олы Хелленгрен и многочисленные публикации в блогах на эту тему с других сайтов). Однако я обнаружил, что ни один из этих ресурсов не содержит рекомендаций или сценариев для поддержки полнотекстовых индексов.

В документации Microsoft упоминается, что дефрагментация индекса b-дерева базовой таблицы и последующее выполнение REORGANIZE для полнотекстового каталога может повысить производительность, но не затрагивает более конкретные рекомендации.

Я также нашел этот вопрос , но он в основном сфокусирован на отслеживании изменений (как обновления данных в базовой таблице распространяются в полнотекстовом индексе), а не на типе регулярно запланированного обслуживания, которое может максимизировать эффективность индекса.

Дополнительная информация: базовое тестирование производительности

Эта SQL-скрипта содержит код, который можно использовать для создания полнотекстового индекса с AUTOотслеживанием изменений и проверки как размера, так и производительности запроса индекса при изменении данных в таблице. Когда я запускаю логику сценария для копии моих производственных данных (в отличие от искусственно созданных данных в скрипте), вот сводка результатов, которые я вижу после каждого шага изменения данных:

введите описание изображения здесь

Несмотря на то, что операторы обновления в этом скрипте были довольно надуманными, эти данные, похоже, показывают, что регулярное обслуживание может принести много пользы

Дополнительная информация: первоначальные идеи

Я думаю о создании еженедельного или еженедельного задания. Кажется, что эта задача может выполнить либо REBUILD, либо REORGANIZE.

Поскольку полнотекстовые индексы могут быть довольно большими (десятки или сотни миллионов строк), я хотел бы иметь возможность определить, достаточно ли фрагментированы индексы в каталоге, чтобы оправдать REBUILD / REORGANIZE. Мне немного непонятно, какая эвристика может иметь для этого смысл.

Джефф Паттерсон
источник

Ответы:

36

Я не смог найти хороших ресурсов в Интернете, поэтому я провел еще несколько практических исследований и подумал, что было бы полезно опубликовать итоговый полнотекстовый план обслуживания, который мы реализуем на основе этого исследования.


Наша эвристика для определения необходимости технического обслуживания

введите описание изображения здесь

Наша основная цель - поддерживать постоянную производительность полнотекстовых запросов по мере эволюции данных в базовых таблицах. Однако по разным причинам нам было бы сложно запускать репрезентативный набор полнотекстовых запросов к каждой из наших баз данных каждую ночь и использовать производительность этих запросов, чтобы определить, когда требуется обслуживание. Поэтому мы стремились создать практические правила, которые можно очень быстро вычислить и использовать в качестве эвристики, чтобы указать, что поддержание полнотекстового индекса может быть оправдано.

В ходе этого исследования мы обнаружили, что системный каталог предоставляет много информации о том, как любой данный полнотекстовый индекс делится на фрагменты. Тем не менее, официальный «фрагментация%» не рассчитывается (как для индексов b-дерева через sys.dm_db_index_physical_stats ). Основываясь на полнотекстовой информации о фрагментах, мы решили вычислить нашу собственную «% полнотекстовой фрагментации». Затем мы использовали сервер разработки для многократного случайного обновления от 100 до 25 000 строк за раз до 10 миллионов строк производственных данных, записи полнотекстовой фрагментации и выполнения эталонного полнотекстового запроса с использованием 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 будут помечены как слишком фрагментированные для оптимальной производительности, поскольку полнотекстовый индекс превышает 1 МБ и фрагментирован как минимум на 10%.

введите описание изображения здесь


Частота обслуживания

У нас уже есть окно ночного обслуживания, и вычисление фрагментации обходится очень дешево. Таким образом, мы будем запускать эту проверку каждую ночь, а затем выполнять только более дорогостоящую операцию по фактической перестройке полнотекстового индекса, когда это необходимо, исходя из порога фрагментации 10%.


REBUILD против REORGANIZE против DROP / CREATE

SQL Server предлагает REBUILDи REORGANIZEпараметры, но они доступны только для полнотекстового каталога (который может содержать любое количество полнотекстовых индексов) в полном объеме. По унаследованным причинам у нас есть один полнотекстовый каталог, который содержит все наши полнотекстовые индексы. Поэтому мы выбрали drop ( DROP FULLTEXT INDEX), а затем заново создать ( CREATE FULLTEXT INDEX) на отдельном уровне полнотекстового индекса.

Возможно, было бы более идеальным логически разбить полнотекстовые индексы на отдельные каталоги и выполнить REBUILDвместо них, но решение drop / create в то же время будет работать для нас.

Джефф Паттерсон
источник