El índice de texto completo de SQL Server 2008 nunca parece completarse


13

Nuestro sitio web tiene una base de datos SQL Server 2008 R2 Express Edition con indexación de texto completo para nuestra búsqueda en el sitio web. Cada vez que se agrega o actualiza un nuevo registro en una de las tablas indexadas, el proceso de indexación nunca parece completarse.

He estado monitoreando el estado durante las últimas semanas utilizando básicamente la misma consulta que se encuentra en este sitio: http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-search/2155/Why-is-this -población-tomando-tan-largo

Esto es lo que veo cuando ejecuto la consulta (haga clic para ver el tamaño completo): Estado del índice de texto completo

Los registros más nuevos en las tablas indexadas nunca se completan y no se pueden buscar. Aunque no hay muchos datos en las tablas, he esperado días para ver si la indexación se completa, pero nada cambia.

La única forma en que puedo lograr que la indexación se complete con éxito es reconstruir el catálogo o descartar y volver a crear todos los índices.

Cada vez que lo hago, el mismo problema termina volviendo tan pronto como se agrega el primer nuevo registro.

Aquí están las estadísticas del servidor por si acaso:

  • Quad-Core AMD Opteron 2.34GHz
  • 4 GB de RAM
  • Windows Server 2008 R2 Enterprise SP1 x64
  • SQL Server 2008 R2 Express Edition con servicios avanzados x64

Respuestas:


6

¡Finalmente encontré la causa de mi problema!

Intenté durante meses rastrear el problema, pero finalmente me di por vencido, deshabilité el seguimiento automático de cambios, simplemente inicié la población incremental manualmente y seguí con mi vida.

Mientras tanto, hubo otro error persistente que estaba teniendo problemas para localizar. Periódicamente, el sitio web arrojaría un error de conexión DB:

No se puede abrir la base de datos "XXXX" solicitada por el inicio de sesión. El inicio de sesión falló. Error de inicio de sesión para el usuario 'XXXX'.

Resultó que ambos problemas tenían la misma solución. Todo lo que tuve que hacer es desactivar una configuración de base de datos llamada Cierre automático. Para hacer esto, simplemente haga clic derecho en la base de datos y haga clic en propiedades. En la ventana de propiedades, seleccione Opciones y establezca "Cierre automático" en falso.

Ventana de propiedades de la base de datos

Tan pronto como desactivé el cierre automático, mis problemas de inicio de sesión de DB desaparecieron y el seguimiento automático de cambios funcionó perfectamente.

Gracias otra vez a todos por su ayuda. ¡Lo aprecio!


3

Curioso si ha seguido los pasos de solución de problemas en BOL para el rendimiento de texto completo: http://technet.microsoft.com/en-us/library/ms142560.aspx .

Apuesto a que SQL Server está consumiendo toda su memoria y no permite que el demonio de filtro tenga ninguno, por lo que su población es lenta, ya que lo más probable es que tenga que cambiar las cosas al archivo de la página. Debería limitar la cantidad de memoria que SQL puede usar (creo que en algún lugar alrededor de 3GB dadas las especificaciones actuales de su sistema, eso dejaría 1GB para FDHost y el sistema operativo).


votando a favor @Brandon. Lea esta sección, "La causa principal de la reducción del rendimiento de indexación de texto completo son los límites de recursos de hardware:"
MacGyver

2

Aquí hay un script que creé usando cursores para reconstruir y llenar índices completos para cualquier tabla que tenga uno para MSSQL2008. Esto funciona en un entorno de producción con bases de datos migradas desde un servidor MSSQL 2000. Desactivé el seguimiento de cambios y simplemente ejecuté este procedimiento almacenado a través del Agente SQL Server. Si estaba usando express, podría usar un script VBS para ejecutarlo a través del Programador de tareas.

Era importante en el script hacer una reconstrucción primero en cada catálogo antes de tratar de llenar los í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

¿Alguien tiene un método que no requiera cursores?


0

Por lo general, se recomienda actualizar el catálogo de texto completo mediante disparadores. Ese es el enfoque que uso en mssql, pero en mi caso porque tengo una aplicación localizada con varios requisitos específicos que me llevan a una solución que utiliza disparadores, esa solución funciona al 100% a partir de 2 años atrás.

Revise su implementación en este ejemplo .


En este momento, mis índices están configurados para el seguimiento automático de cambios. He leído que cambiarlo a manual y usar disparadores en realidad puede causar problemas cuando una persona inserta o actualiza un registro en una tabla indexada antes de que la actualización de índice disparada de la actualización de la tabla anterior aún no haya terminado. Parece que el seguimiento automático de cambios debería funcionar ... especialmente porque no tengo tantos registros en mis tablas.
Jargs

Revisé mi configuración con el enlace de ejemplo que proporcionó, pero todo parece estar en orden. Incluso intenté reparar mi instalación de SQL Server, pero el problema persiste.
Jargs

1
No sé si esto está relacionado, pero una vez tuve un problema con la población de catálogos de texto completo debido a problemas de Word Breaker. Si abre SSMS y selecciona Almacenamiento en su base de datos, haga clic derecho en el catálogo de texto completo. Vaya a Tablas / Vistas y mire el Idioma para Word Breaker. ¿Hay columnas que usan diferentes idiomas para los separadores de palabras? He notado que si tiene diferentes idiomas para Word Breakers en la misma tabla, la población no funciona. Tal vez sin relación, pero ¿quién sabe?
Craig Efrein

0

No estoy seguro de cuál es la causa raíz de su situación, pero esto puede suceder después de una copia de seguridad. No estoy seguro de si eso es lo que está sucediendo en su caso o cómo esa tabla es diferente de las demás. Ahora me tienes curiosidad. ¿Tiene activada la replicación SQL?

Para una solución temporal, realizaría un "rastreo" (población) en la tabla cuando esto ocurra.

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

Usa este código:

ALTER FULLTEXT INDEX ON dbname.dbo.tablename
START FULL POPULATION;
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.