Come faccio a sapere quando Indice SQL testo popolazione è finito?
-
02-10-2019 - |
Domanda
Siamo scrittura di unit test per la nostra applicazione ASP.NET che funzionano contro un database di test di SQL Server. Cioè, il metodo ClassInitialize crea un nuovo database con dati di test, e il ClassCleanup elimina il database. Facciamo questo mediante l'esecuzione di script .bat dal codice.
Le classi in prova viene dato uno stringa di connessione che si connette al database di test unità anziché un database di produzione.
Il nostro problema è, che il database contiene un indice testo completo, che deve essere completamente popolato con i dati del test in modo che i nostri test da eseguire come previsto.
Per quanto posso dire, l'indice full-text è sempre popolata in background. Vorrei essere in grado, a:
- Crea l'indice completo di testo, completamente popolato, con un sincrono (Transact-SQL?) Dichiarazione, o
- Scopri quando la popolazione full-text è finito, c'è un'opzione di callback, o posso chiedere più volte?
La mia soluzione attuale è quella di forzare un ritardo alla fine il metodo della classe di inizializzazione - 5 secondi sembra funzionare -. Perché non riesco a trovare nulla nella documentazione
Soluzione
E 'possibile interrogare lo stato utilizzando FULLTEXTCATALOGPROPERTY (vedi qui: http: // TechNet .microsoft.com / en-us / library / ms190370.aspx ).
Ad esempio:
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
Si potrebbe anche come utilizzare SQL Profiler per monitorare ciò che i comandi problemi di SQL Server Management Studio quando si mettono le proprietà finestra di dialogo per il catalogo. La finestra di dialogo include un'indicatin dello stato della popolazione e tutte le informazioni visualizzate viene interrogato tramite T-SQL.
Altri suggerimenti
Vorrei offrire una versione più facile da leggere della risposta di @ Daniel Renshaw:
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
Risultati:
LastPopulated PopulateStatus
----------------------- ----------------------------------
2012-05-08 14:51:37.000 Idle
(1 row(s) affected)
Questa è una stored procedure che abbiamo creato in base alla risposta del GarethOwen. Si accetta un elenco separato da virgole di tabelle come parametri e attende fino a quando gli indici full-text su tutti loro sono stati aggiornati. Lo fa questo controllo ogni decimo di secondo per evitare thrashing disco e timeout dopo 10 secondi nel caso in cui le cose sono in esecuzione lentamente / rotto. Utile se le ricerche di FT sono su più indici.
Chiamato nel seguente modo:
EXECUTE [dbo].[WaitForFullTextIndexing] 'MY_TABLE,ALTERNATE_NAMES,TAG_GROUP_VALUES,TAG_GROUPS,FIELD_OPTION';
La fonte:
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 è una funzione del valore tabella che tutti devono avere ormai che divide una stringa su un separatore in una tabella temporanea:
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
Grazie Daniel, la tua risposta mi ha fatto sulla strada giusta.
Io in realtà utilizzare la seguente istruzione T-SQL per chiedere se lo stato della popolazione dell'indice testo completo è in standby:
SELECT OBJECTPROPERTY(object_id('v_doc_desc_de'), 'TableFulltextPopulateStatus')
'v_doc_desc_de' è il nome della vista database che abbiamo indice.
Se lo stato della popolazione non è inattivo, ho attendere un paio di secondi e di chiedere di nuovo, fino a quando è inattivo. E 'importante aspettare un po' di tempo tra i controlli per garantire alla popolazione di testo completo non è rallentato controllando continuamente lo stato della popolazione.
Il MSDN documentazione afferma che la funzione OBJECTPROPERTYEX
(a livello di tabella) si consiglia l'affermazione FULLTEXTCATALOGPROPERTY
con la proprietà 'PopulateStatus'. Essa afferma quanto segue:
Le seguenti proprietà verrà rimossa in una versione futura di SQL Server: logsize e PopulateStatus. Evitare l'uso di queste proprietà in nuovo progetto di sviluppo e prevedere interventi di modifica delle applicazioni che utilizzano uno qualsiasi di loro.
Per attendere un catalogo testo completo della popolazione finitura di tutte le sue tabelle e viste senza dover specificare i loro nomi, è possibile utilizzare la seguente stored procedure. Si tratta di una combinazione di risposta di JohnB a questa domanda e la risposta da cezarm ad una domanda relativa :
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