Wie kann ich wissen, wann SQL Volltext-Index Bevölkerung fertig ist?
-
02-10-2019 - |
Frage
Wir schreiben Unit-Tests für unsere ASP.NET-Anwendung, dass gegen einen Test SQL Server-Datenbank ausgeführt werden. Das heißt, schafft die ClassInitialize Methode eine neue Datenbank mit Testdaten und die ClassCleanup löschen die Datenbank. Wir tun dies, indem .bat Skripte von Code ausgeführt wird.
Die Klassen im Test gegeben sind eine Verbindungszeichenfolge, dass eine Verbindung mit der Unit-Test-Datenbank statt einer Produktionsdatenbank.
Unser Problem ist, dass die Datenbank einen Volltextindex enthält, die vollständig mit den Testdaten, um für unsere Tests aufgefüllt werden muss laufen wie erwartet.
Soweit ich sagen kann, ist der Volltextindex immer im Hintergrund gefüllt. Ich möchte entweder zu:
- Erstellen Sie den Volltextindex, voll bestückt, mit einem synchronen (Transact-SQL?) Anweisung oder
- Finden Sie heraus, wenn die Volltext Bevölkerung fertig ist, gibt es eine Rückrufoption, oder kann ich fragen wiederholt?
Meine aktuelle Lösung ist am Ende Methode der Klasse initialize eine Verzögerung zu zwingen - 5 Sekunden zu arbeiten scheinen -. Weil ich nichts in der Dokumentation finden
Lösung
Sie können den Status abfragen FULL (siehe hier: http: // technet .microsoft.com / en-us / library / ms190370.aspx ).
Zum Beispiel:
SELECT
FULLTEXTCATALOGPROPERTY(cat.name,'ItemCount') AS [ItemCount],
FULLTEXTCATALOGPROPERTY(cat.name,'MergeStatus') AS [MergeStatus],
FULLTEXTCATALOGPROPERTY(cat.name,'PopulateCompletionAge') AS [PopulateCompletionAge],
FULLTEXTCATALOGPROPERTY(cat.name,'PopulateStatus') AS [PopulateStatus],
FULLTEXTCATALOGPROPERTY(cat.name,'ImportStatus') AS [ImportStatus]
FROM sys.fulltext_catalogs AS cat
Sie können auch wie SQL Profiler verwenden, um zu überwachen, welche Befehle Probleme SQL Server Management Studio, wenn Sie die Eigenschaften für den Katalog-Dialog aufzurufen. Der Dialog enthält eine indicatin Bevölkerungsstand und alle Informationen angezeigt wird, mit T-SQL abgefragt werden.
Andere Tipps
Ich mag eine einfacher zu lesende Version von @ Daniel Renshaw Antwort bieten:
DECLARE @CatalogName VARCHAR(MAX)
SET @CatalogName = 'FTS_Demo_Catalog'
SELECT
DATEADD(ss, FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateCompletionAge'), '1/1/1990') AS LastPopulated
,(SELECT CASE FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateStatus')
WHEN 0 THEN 'Idle'
WHEN 1 THEN 'Full Population In Progress'
WHEN 2 THEN 'Paused'
WHEN 3 THEN 'Throttled'
WHEN 4 THEN 'Recovering'
WHEN 5 THEN 'Shutdown'
WHEN 6 THEN 'Incremental Population In Progress'
WHEN 7 THEN 'Building Index'
WHEN 8 THEN 'Disk Full. Paused'
WHEN 9 THEN 'Change Tracking' END) AS PopulateStatus
FROM sys.fulltext_catalogs AS cat
Ergebnisse:
LastPopulated PopulateStatus
----------------------- ----------------------------------
2012-05-08 14:51:37.000 Idle
(1 row(s) affected)
Dies ist eine gespeicherte Prozedur wir auf GarethOwen Antwort erstellt basiert. Er akzeptiert eine durch Kommata getrennte Liste von Tabellen als Parameter und wartet, bis zur Volltextindizes für alle von ihnen wurden aktualisiert. Es tut diese Prüfung jedes Zehntel einer Sekunde heraus nach 10 Sekunden Dreschen die Scheibe und mal die Dinge nur für den Fall zu verhindern, werden langsam / gebrochen läuft. Nützlich, wenn Sie Ihre FT-Suchen sind über mehrere Indizes.
Wird aufgerufen, auf folgende Weise:
EXECUTE [dbo].[WaitForFullTextIndexing] 'MY_TABLE,ALTERNATE_NAMES,TAG_GROUP_VALUES,TAG_GROUPS,FIELD_OPTION';
Die Quelle:
CREATE PROCEDURE WaitForFullTextIndexing
@TablesStr varchar(max)
AS
BEGIN
DECLARE @Tables AS TABLE( [word] [varchar](8000) NULL)
INSERT INTO @Tables (word) SELECT items from dbo.Split(@TablesStr, ',');
DECLARE @NumberOfTables int;
SELECT @NumberOfTables = COUNT(*) from @Tables;
DECLARE @readyCount int;
SET @readyCount = 0;
DECLARE @waitLoops int;
SET @waitLoops = 0;
DECLARE @result bit;
WHILE @readyCount <> @NumberOfTables AND @waitLoops < 100
BEGIN
select @readyCount = COUNT(*)
from @Tables tabs
where OBJECTPROPERTY(object_id(tabs.word), 'TableFulltextPopulateStatus') = 0;
IF @readyCount <> @NumberOfTables
BEGIN
-- prevent thrashing
WAITFOR DELAY '00:00:00.1';
END
set @waitLoops = @waitLoops + 1;
END
END
GO
dbo.split ist ein Tabellenwert-Funktion, dass jeder jetzt haben muss, die einen String auf einem Separator in eine temporäre Tabelle teilt:
CREATE FUNCTION [dbo].[Split](@String varchar(8000), @Delimiter char(1))
returns @temptable TABLE (items varchar(8000))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end
GO
Danke Daniel, deine Antwort hat mich auf dem richtigen Weg.
Ich benutze die folgende T-SQL-Anweisung zu fragen, ob die Bevölkerung Status des Volltextindex ist Idle:
SELECT OBJECTPROPERTY(object_id('v_doc_desc_de'), 'TableFulltextPopulateStatus')
'v_doc_desc_de' ist der Name der Datenbank Ansicht, dass wir Index.
Wenn die Bevölkerung Status nicht im Leerlauf ist, warte ich ein paar Sekunden, und wieder fragen, bis sie frei ist. Es ist wichtig, eine geringe Menge an Zeit zwischen den Prüfungen zu warten, die vollständigen Text Bevölkerung gewährleistet ist, nicht durch die kontinuierliche Überprüfung der Bevölkerung Status verlangsamt.
Die MSDN-Dokumentation besagt, dass die OBJECTPROPERTYEX
Funktion (auf Tabellenebene) über die FULLTEXTCATALOGPROPERTY
Erklärung mit Eigentum ‚PopulateStatus‘ empfohlen. Darin heißt es wie folgt zusammen:
LogSize und PopulateStatus:Die folgenden Eigenschaften werden in einer zukünftigen Version von SQL Server entfernt werden. Vermeiden Sie diese Eigenschaften in neuer Entwicklungsarbeit und Plan-Anwendungen zu ändern, die derzeit irgendwelche von ihnen verwenden.
Um sich für einen Volltextkatalog bis Ende der Belegung aller seiner Tabellen und Views zu warten, ohne ihre Namen angeben, können Sie die folgende gespeicherte Prozedur verwenden. Dies ist eine Kombination von JohnB Antwort auf diese Frage und die Antwort von cezarm auf eine damit verbundene Frage
CREATE PROCEDURE WaitForFullTextIndexing
@CatalogName VARCHAR(MAX)
AS
BEGIN
DECLARE @status int;
SET @status = 1;
DECLARE @waitLoops int;
SET @waitLoops = 0;
WHILE @status > 0 AND @waitLoops < 100
BEGIN
SELECT @status = FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateStatus')
FROM sys.fulltext_catalogs AS cat;
IF @status > 0
BEGIN
-- prevent thrashing
WAITFOR DELAY '00:00:00.1';
END
SET @waitLoops = @waitLoops + 1;
END
END