Diretrizes para manutenção de índice de texto completo

29

Quais diretrizes devem ser consideradas para manter índices de texto completo?

Devo RECONSTRUIR ou REORGANIZAR o catálogo de texto completo (consulte BOL )? O que é uma cadência de manutenção razoável? Quais heurísticas (semelhantes aos limiares de fragmentação de 10% e 30%) poderiam ser usadas para determinar quando a manutenção é necessária?

(Tudo abaixo é simplesmente informações extras, elaborando a pergunta e mostrando o que eu pensei até agora.)



Informações adicionais: minha pesquisa inicial

Existem muitos recursos na manutenção do índice b-tree (por exemplo, esta pergunta , os scripts de Ola Hallengren e várias postagens no blog sobre o assunto de outros sites). No entanto, descobri que nenhum desses recursos fornece recomendações ou scripts para manter índices de texto completo.

Existe uma documentação da Microsoft que menciona que desfragmentar o índice da árvore b da tabela base e, em seguida, executar uma REORGANIZE no catálogo de texto completo pode melhorar o desempenho, mas não toca em recomendações mais específicas.

Eu também encontrei essa pergunta , mas ela se concentra principalmente no rastreamento de alterações (como as atualizações de dados na tabela subjacente são propagadas no índice de texto completo) e não no tipo de manutenção programada regularmente que pode maximizar a eficiência do índice.

Informações adicionais: teste de desempenho básico

Este SQL Fiddle contém código que pode ser usado para criar um índice de texto completo com AUTOcontrole de alterações e examinar o tamanho e o desempenho da consulta do índice, à medida que os dados na tabela são modificados. Quando executo a lógica do script em uma cópia dos meus dados de produção (em oposição aos dados fabricados artificialmente no violino), aqui está um resumo dos resultados que estou vendo após cada etapa de modificação de dados:

insira a descrição da imagem aqui

Embora as instruções de atualização neste script tenham sido razoavelmente inventadas, esses dados parecem mostrar que há muito a ser ganho pela manutenção regular.

Informações adicionais: Idéias iniciais

Estou pensando em criar uma tarefa noturna ou semanal. Parece que esta tarefa pode executar um RECONSTRUÇÃO ou REORGANIZAR.

Como os índices de texto completo podem ser bastante grandes (dezenas ou centenas de milhões de linhas), eu gostaria de poder detectar quando os índices no catálogo estão suficientemente fragmentados para garantir uma REBUILD / REORGANIZE. Não sei ao certo o que a heurística pode fazer sentido para isso.

Geoff Patterson
fonte

Respostas:

36

Não consegui encontrar bons recursos on-line, por isso fiz mais pesquisas práticas e achei que seria útil publicar o plano de manutenção de texto completo resultante que estamos implementando com base nessa pesquisa.


Nossa heurística para determinar quando a manutenção é necessária

insira a descrição da imagem aqui

Nosso principal objetivo é manter um desempenho consistente da consulta de texto completo conforme os dados evoluem nas tabelas subjacentes. No entanto, por várias razões, seria difícil lançar um conjunto representativo de consultas de texto completo em cada um de nossos bancos de dados todas as noites e usar o desempenho dessas consultas para determinar quando a manutenção é necessária. Portanto, procurávamos criar regras práticas que pudessem ser computadas muito rapidamente e usadas como uma heurística para indicar que a manutenção do índice de texto completo pode ser justificada.

No decorrer desta exploração, descobrimos que o catálogo do sistema fornece muitas informações sobre como qualquer índice de texto completo é dividido em fragmentos. No entanto, não há "fragmentação%" oficial calculada (como existe para os índices da árvore b através de sys.dm_db_index_physical_stats ). Com base nas informações do fragmento de texto completo, decidimos calcular nossa própria "% de fragmentação de texto completo". Em seguida, usamos um servidor de desenvolvimento para fazer repetidamente atualizações aleatórias de qualquer lugar entre 100 e 25.000 linhas por vez para uma cópia de 10 milhões de linhas de dados de produção, registrar a fragmentação de texto completo e executar uma consulta de referência em texto completo usando CONTAINSTABLE.

Os resultados, como vistos nos gráficos acima e abaixo, foram muito esclarecedores e mostraram que a medida de fragmentação que criamos é altamente correlacionada com o desempenho observado. Como isso também está relacionado às nossas observações qualitativas na produção, basta que nos sintamos confortáveis ​​usando a% de fragmentação como nossa heurística para decidir quando nossos índices de texto completo precisam de manutenção.

insira a descrição da imagem aqui


O plano de manutenção

Decidimos usar o código a seguir para calcular uma% de fragmentação para cada índice de texto completo. Quaisquer índices de texto completo de tamanho não trivial com fragmentação de pelo menos 10% serão sinalizados para serem reconstruídos pela nossa manutenção durante a noite.

-- 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

Essas consultas geram resultados como os seguintes e, nesse caso, as linhas 1, 6 e 9 seriam marcadas como muito fragmentadas para um desempenho ideal, pois o índice de texto completo tem mais de 1 MB e pelo menos 10% de fragmentação.

insira a descrição da imagem aqui


Cadência de manutenção

Já temos uma janela de manutenção noturna e o cálculo da fragmentação é muito barato de calcular. Portanto, executaremos essa verificação todas as noites e, em seguida, apenas realizaremos a operação mais cara de reconstruir um índice de texto completo quando necessário, com base no limite de 10% de fragmentação.


REBUILD vs. REORGANIZE vs. DROP / CREATE

Ofertas REBUILDe REORGANIZEopções do SQL Server , mas elas estão disponíveis apenas para um catálogo de texto completo (que pode conter qualquer número de índices de texto completo) em sua totalidade. Por motivos herdados, temos um único catálogo de texto completo que contém todos os nossos índices de texto completo. Portanto, optamos por soltar ( DROP FULLTEXT INDEX) e depois recriar ( CREATE FULLTEXT INDEX) em um nível de índice de texto completo individual.

Pode ser mais ideal dividir os índices de texto completo em catálogos separados de uma maneira lógica e executar uma REBUILDsubstituição, mas a solução de criação / exclusão funcionará para nós nesse meio tempo.

Geoff Patterson
fonte