O índice de texto completo do SQL Server 2008 nunca parece completo

13

Nosso site possui um banco de dados do SQL Server 2008 R2 Express Edition com indexação de texto completo para a pesquisa no site. Sempre que um novo registro é adicionado ou atualizado em uma das tabelas indexadas, o processo de indexação nunca parece ser concluído.

Eu tenho monitorado o status nas últimas semanas usando basicamente a mesma consulta encontrada neste site: http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-search/2155/Why-is-this -população-demorando tanto

É isso que vejo quando executo a consulta (clique para ver o tamanho completo): Status do índice de texto completo

Os registros mais recentes nas tabelas indexadas nunca são concluídos e não são pesquisáveis. Mesmo que não haja muitos dados nas tabelas, esperei dias para ver se a indexação é concluída, mas nada muda.

A única maneira de conseguir concluir a indexação com êxito é recriar o catálogo ou descartar e recriar todos os índices.

Toda vez que faço isso, o mesmo problema acaba voltando assim que o primeiro novo registro é adicionado.

Aqui estão as estatísticas do servidor por precaução:

  • AMD Opteron de núcleo quádruplo 2.34GHz
  • 4GB RAM
  • Windows Server 2008 R2 Enterprise SP1 x64
  • SQL Server 2008 R2 Express Edition com Serviços Avançados x64
Jargs
fonte

Respostas:

6

Finalmente encontrei a causa do meu problema!

Tentei durante meses rastrear o problema, mas finalmente desisti, desabilitei o rastreamento automático de alterações, iniciei manualmente a população incremental e segui em frente com minha vida.

Enquanto isso, havia outro erro irritante que eu estava tendo problemas para rastrear. Periodicamente, o site gerava um erro de conexão com o banco de dados:

Não é possível abrir o banco de dados "XXXX" solicitado pelo login. O login falhou. Falha no login para o usuário 'XXXX'.

Aconteceu que esses dois problemas tinham a mesma solução. Tudo o que eu precisava fazer era desativar uma configuração de banco de dados chamada Auto Close. Para fazer isso, clique com o botão direito do mouse no banco de dados e clique em Propriedades. Na janela de propriedades, selecione Opções e defina "Fechamento automático" como falso.

Janela Propriedades do Banco de Dados

Assim que desabilitei o fechamento automático, meus problemas de login no banco de dados desapareceram e o rastreamento automático de alterações funcionou perfeitamente.

Obrigado novamente pela ajuda de todos. Eu agradeço!

Jargs
fonte
3

Curioso se você passou pelas etapas de solução de problemas no BOL para desempenho de texto completo - http://technet.microsoft.com/en-us/library/ms142560.aspx .

Aposto que o SQL Server está consumindo toda a sua memória e não deixando o daemon de filtro ter nenhuma, portanto sua população é lenta, pois é mais provável que tenha que trocar as coisas pelo arquivo de paginação. Você deve limitar a quantidade de memória que o SQL pode usar (eu acho que algo em torno de 3 GB, dadas as especificações atuais do sistema - isso deixaria 1 GB para o FDHost e o sistema operacional).

Brandon
fonte
votação antecipada @Brandon. Leia esta seção, "A principal causa do desempenho reduzido da indexação de texto completo são os limites de recursos de hardware:"
MacGyver
2

Aqui está um script que eu criei usando cursores para reconstruir e preencher índices completos para qualquer tabela que tenha um para MSSQL2008. Isso está funcionando em um ambiente de produção com bancos de dados migrados de um servidor MSSQL 2000. Desativei o rastreamento de alterações e apenas execute este procedimento armazenado via SQL Server Agent. Se você estiver usando express, poderá usar um script VBS para executá-lo via Agendador de tarefas.

Era importante no script fazer uma reconstrução primeiro em cada catálogo antes de tentar preencher os índices.

CREATE PROCEDURE [dbo].[rebuild_repopulate_fulltext] 
AS
BEGIN

Declare @cmdA NVARCHAR(255)
Declare @cmdB NVARCHAR(255)
Declare @cmdC NVARCHAR(255)
DECLARE @Database VARCHAR(255)   
DECLARE @Table VARCHAR(255)  
DECLARE @cmd NVARCHAR(500)  
DECLARE @fillfactor INT 
DECLARE @Catalog VARCHAR(255)
DECLARE @Schema VARCHAR(255)

SET @fillfactor = 90 

DECLARE DatabaseCursor CURSOR FOR  
SELECT name FROM MASTER.dbo.sysdatabases   
WHERE name NOT IN ('master','msdb','tempdb','model','distribution')   
ORDER BY 1  

OPEN DatabaseCursor  

FETCH NEXT FROM DatabaseCursor INTO @Database  
WHILE @@FETCH_STATUS = 0  
BEGIN  

   -- rebuild fulltext catalog
   set @cmd = 'DECLARE CatalogCursor CURSOR FOR 
        SELECT t.name AS TableName, c.name AS FTCatalogName, s.name as schemaname
        FROM ['+ @Database + '].sys.tables t JOIN ['+ @Database +'].sys.fulltext_indexes i
        ON t.object_id = i.object_id
        JOIN ['+ @Database + '].sys.fulltext_catalogs c
        ON i.fulltext_catalog_id = c.fulltext_catalog_id
        JOIN ['+ @Database + '].sys.schemas s ON t.schema_id = s.schema_id'
   --PRINT @cmd
   EXEC (@cmd)  


   OPEN CatalogCursor   

   FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   WHILE @@FETCH_STATUS = 0   
   BEGIN  

    SET @cmdB = 'USE ['+ @Database + ']; ALTER FULLTEXT CATALOG ' + @Catalog + ' REBUILD;'
    --PRINT @cmdB
    EXEC (@cmdB)


    FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   END   

   CLOSE CatalogCursor   


   OPEN CatalogCursor   

   FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   WHILE @@FETCH_STATUS = 0   
   BEGIN  

    SET @cmdC = 'USE ['+ @Database + ']; ALTER FULLTEXT INDEX ON ['+ @Database + '].[' + @Schema + '].[' + @Table + '] START FULL POPULATION;' 
    --PRINT @cmdC
    EXEC (@cmdC)

    FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   END   

   CLOSE CatalogCursor   
   DEALLOCATE CatalogCursor  



   FETCH NEXT FROM DatabaseCursor INTO @Database  
END  

CLOSE DatabaseCursor   
DEALLOCATE DatabaseCursor

END

Alguém tem um método que não requer cursores?

Craig Efrein
fonte
0

Geralmente é recomendável atualizar o catálogo de texto completo usando gatilhos. Essa é a abordagem que uso no mssql, mas no meu caso, porque tenho um aplicativo localizado com vários requisitos específicos que me levam a uma solução usando gatilhos, que soluções funcionam 100% a partir de 2 anos atrás.

Revise sua implementação neste exemplo .

Rui Marques
fonte
No momento, meus índices estão definidos para o rastreamento automático de alterações. Eu li que alterá-lo para manual e usar acionadores pode realmente causar problemas quando uma pessoa insere ou atualiza um registro em uma tabela indexada antes que a atualização do índice acionado da atualização da tabela anterior ainda não tenha sido concluída. Parece que o rastreamento automático de alterações deve funcionar ... especialmente porque não tenho muitos registros em minhas tabelas.
Jargs
Analisei minha configuração com base no link de exemplo que você forneceu, mas tudo parece estar em ordem. Eu até tentei reparar minha instalação do SQL Server, mas o problema permanece.
Jargs 01/12/19
1
Não sei se isso está relacionado, mas uma vez tive um problema com a população de registros de texto completo devido a problemas com o Word Breaker. Se você abrir o SSMS e selecionar Armazenamento no seu banco de dados, clique com o botão direito do mouse no catálogo de texto completo. Vá para Tabelas / exibições e consulte o Language for Word Breaker. Existem colunas que usam idiomas diferentes para separadores de palavras? Percebi que, se você tiver idiomas diferentes para o Word Breakers na mesma tabela, a população não funcionará. Talvez não relacionado, mas quem sabe?
Craig Efrein
0

Não sei qual é a causa raiz da sua situação, mas isso pode acontecer após a ocorrência de um backup. Não tenho certeza se é isso que está acontecendo no seu caso ou se essa tabela é diferente das outras. Agora você me deixa curioso. Você tem a replicação SQL ativada?

Para uma correção temporária, eu executaria um "Rastreamento" (população) na tabela quando isso acontecer.

http://msdn.microsoft.com/en-us/library/ms142575(v=sql.105).aspx

Use este código:

ALTER FULLTEXT INDEX ON dbname.dbo.tablename
START FULL POPULATION;
MacGyver
fonte