Der SQL Server 2008-Volltextindex scheint nie vollständig zu sein

13

Unsere Website verfügt über eine SQL Server 2008 R2 Express Edition-Datenbank mit Volltextindizierung für unsere Website-Suche. Jedes Mal, wenn ein neuer Datensatz in einer der indizierten Tabellen hinzugefügt oder aktualisiert wird, scheint der Indizierungsprozess niemals abgeschlossen zu sein.

Ich habe den Status in den letzten Wochen mithilfe der gleichen Abfrage überwacht, die auf dieser Website gefunden wurde: http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-search/2155/Why-is-this Bevölkerung, die so lange dauert

Folgendes wird beim Ausführen der Abfrage angezeigt (Klicken für volle Größe): Volltextindexstatus

Die neuesten Datensätze in den indizierten Tabellen werden nie vollständig und können nicht durchsucht werden. Obwohl die Tabellen nicht sehr viele Daten enthalten, habe ich tagelang darauf gewartet, ob die Indizierung abgeschlossen ist, aber es ändert sich nichts.

Die einzige Möglichkeit, die Indizierung erfolgreich abzuschließen, besteht darin, entweder den Katalog neu zu erstellen oder alle Indizes zu löschen und neu zu erstellen.

Jedes Mal, wenn ich das getan habe, kehrt das gleiche Problem zurück, sobald der erste neue Datensatz hinzugefügt wird.

Hier sind die Serverstatistiken für den Fall:

  • Quad-Core AMD Opteron 2,34 GHz
  • 4 GB RAM
  • Windows Server 2008 R2 Enterprise SP1 x64
  • SQL Server 2008 R2 Express Edition mit Advanced Services x64
Jargs
quelle

Antworten:

6

Ich habe endlich die Ursache für mein Problem gefunden!

Ich habe monatelang versucht, das Problem aufzuspüren, aber schließlich aufgehört, die automatische Änderungsverfolgung zu deaktivieren, nur manuell die inkrementelle Auffüllung eingeleitet und mein Leben fortgesetzt.

In der Zwischenzeit gab es einen weiteren quälenden Fehler, bei dem ich Probleme hatte, ihn aufzuspüren. In regelmäßigen Abständen gab die Website einen DB-Verbindungsfehler aus:

Die vom Login angeforderte Datenbank "XXXX" kann nicht geöffnet werden. Die Anmeldung ist fehlgeschlagen. Anmeldung für Benutzer 'XXXX' fehlgeschlagen.

Es stellte sich heraus, dass beide Probleme die gleiche Lösung hatten. Alles was ich tun musste, war eine Datenbankeinstellung namens Auto Close auszuschalten. Klicken Sie dazu mit der rechten Maustaste auf die Datenbank und klicken Sie auf Eigenschaften. Wählen Sie im Eigenschaftenfenster Optionen und setzen Sie "Automatisch schließen" auf "Falsch".

Datenbankeigenschaften-Fenster

Sobald ich das automatische Schließen deaktiviert hatte, verschwanden meine Probleme mit der DB-Anmeldung und die automatische Änderungsverfolgung funktionierte einwandfrei.

Nochmals vielen Dank für die Hilfe aller. Ich schätze es!

Jargs
quelle
3

Neugierig, wenn Sie die Schritte zur Fehlerbehebung in BOL für die Volltextleistung ausgeführt haben - http://technet.microsoft.com/en-us/library/ms142560.aspx .

Ich wette, dass SQL Server Ihren gesamten Speicher belegt und den Filter-Daemon nicht zulässt, sodass Ihre Population langsam ist, da es höchstwahrscheinlich erforderlich ist, Daten in die Auslagerungsdatei zu tauschen. Sie sollten die Menge an Arbeitsspeicher, die SQL verwenden kann, begrenzen (ich würde denken, dass sie bei Ihren aktuellen Systemspezifikationen etwa 3 GB beträgt - das würde 1 GB für FDHost und das Betriebssystem übrig lassen).

Brandon
quelle
Up-Voting @Brandon. Lesen Sie diesen Abschnitt, "Die Hauptursache für die verringerte Leistung der Volltextindizierung sind Hardware-Ressourcenbeschränkungen:"
MacGyver,
2

Hier ist ein Skript, das ich mithilfe von Cursorn erstellt habe, um vollständige Indizes für alle Tabellen mit einem Index für MSSQL2008 neu zu erstellen und aufzufüllen. Dies funktioniert in einer Produktionsumgebung mit Datenbanken, die von einem MSSQL 2000-Server migriert wurden. Ich habe die Änderungsnachverfolgung deaktiviert und diese gespeicherte Prozedur nur über den SQL Server-Agenten ausgeführt. Wenn Sie Express verwenden, können Sie ein VBS-Skript verwenden, um es über den Taskplaner auszuführen.

Im Skript war es wichtig, zuerst einen Neuaufbau für jeden Katalog durchzuführen, bevor versucht wird, die Indizes aufzufüllen.

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

Hat jemand eine Methode, die keine Cursor benötigt?

Craig Efrein
quelle
0

In der Regel wird empfohlen, den Volltextkatalog mithilfe von Triggern zu aktualisieren. Dies ist der Ansatz, den ich für mssql verwende. Da ich jedoch eine lokalisierte Anwendung mit mehreren spezifischen Anforderungen habe, die mich zu einer Lösung mit Triggern führen, funktioniert diese Lösung ab 2 Jahren zu 100%.

Überprüfen Sie Ihre Implementierung anhand dieses Beispiels .

Rui Marques
quelle
Momentan sind meine Indizes auf automatische Änderungsnachverfolgung eingestellt. Ich habe gelesen, dass eine manuelle Änderung und die Verwendung von Triggern tatsächlich Probleme verursachen kann, wenn eine Person einen Datensatz in eine indizierte Tabelle einfügt oder aktualisiert, bevor die ausgelöste Indexaktualisierung aus der vorherigen Tabellenaktualisierung noch nicht abgeschlossen ist. Anscheinend sollte die automatische Änderungsnachverfolgung funktionieren, zumal ich nicht so viele Datensätze in meinen Tabellen habe.
Jargs
Ich habe mein Setup anhand des von Ihnen angegebenen Beispiellinks überprüft, aber alles scheint in Ordnung zu sein. Ich habe sogar versucht, meine SQL Server-Installation zu reparieren, aber das Problem bleibt bestehen.
Jargs
1
Ich weiß nicht, ob dies im Zusammenhang steht, aber ich hatte einmal ein Problem mit der Volltextkatalog-Population aufgrund von Word Breaker-Problemen. Wenn Sie SSMS öffnen und Speicher unter Ihrer Datenbank auswählen, klicken Sie mit der rechten Maustaste auf den Volltextkatalog. Gehen Sie zu Tables / Views und sehen Sie sich die Sprache für Word Breaker an. Gibt es Spalten, die unterschiedliche Sprachen für Worttrenner verwenden? Mir ist aufgefallen, dass die Population nicht funktioniert, wenn Sie in derselben Tabelle verschiedene Sprachen für Word Breaker haben. Vielleicht ohne Bezug, aber wer weiß?
Craig Efrein
0

Sie sind sich nicht sicher, welche Ursache in Ihrer Situation liegt. Dies kann jedoch passieren, nachdem eine Sicherung durchgeführt wurde. Nicht sicher, ob das in Ihrem Fall der Fall ist oder wie sich diese Tabelle von den anderen unterscheidet. Jetzt hast du mich neugierig. Haben Sie die SQL-Replikation aktiviert?

Für eine vorübergehende Korrektur würde ich in diesem Fall ein "Crawling" (Auffüllung) für die Tabelle durchführen.

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

Verwenden Sie diesen Code:

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