我怎么知道SQL全文索引填充何时完成?

Gar*_*wen 56 sql-server unit-testing population fulltext-index

我们正在编写针对测试SQL Server数据库运行的ASP.NET应用程序的单元测试.也就是说,ClassInitialize方法使用测试数据创建一个新数据库,ClassCleanup删除数据库.我们通过从代码运行.bat脚本来完成此操作.

测试中的类被赋予连接字符串,该字符串连接到单元测试数据库而不是生产数据库.

我们的问题是,数据库包含全文索引,需要使用测试数据完全填充,以便我们的测试按预期运行.

据我所知,全文索引总是在后台填充.我希望能够:

  1. 使用同步(transact-SQL?)语句创建完整填充的全文索引,或
  2. 找出完整文本填充的时间,是否有回调选项,或者我可以反复询问?

我目前的解决方案是在类初始化方法结束时强制延迟 - 5秒似乎工作 - 因为我在文档中找不到任何东西.

Tom*_*day 63

我想提供一个更容易阅读的@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
Run Code Online (Sandbox Code Playgroud)

结果:

LastPopulated           PopulateStatus
----------------------- ----------------------------------
2012-05-08 14:51:37.000 Idle

(1 row(s) affected)
Run Code Online (Sandbox Code Playgroud)

  • 将此与 Daniel Renshaw 的答案相结合,可以很好地查询多个目录。 (2认同)
  • 不使用任何内容时,为什么还要查询sys.fulltext_catalogs表?您不妨删除查询的最后一行。或者,也可以删除@CatalogName变量,并在SELECT语句中使用[name]。 (2认同)

Dan*_*haw 45

您可以使用FULLTEXTCATALOGPROPERTY查询状态(请参阅此处:http://technet.microsoft.com/en-us/library/ms190370.aspx).

例如:

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
Run Code Online (Sandbox Code Playgroud)

您可能还希望使用SQL事件探查器来监视在打开目录的属性对话框时SQL Server Management Studio发出的命令.该对话框包含人口状态的指示,所有显示的信息都是使用T-SQL查询的.

  • 我遇到过一个页面,指出“PopulateStatus”属性在 SQL Server 的未来版本中将被/将被弃用,但我一直无法找到检查人口状态的替代方法。你有什么想法?请参阅第一个注释:http://technet.microsoft.com/en-us/library/ms190370.aspx (2认同)

小智 10

这是我们根据GarethOwen的答案创建的存储过程.它接受以逗号分隔的表列表作为参数,并等待所有表的全文索引更新.它每隔十分之一秒进行一次检查,以防止颠簸磁盘并在10秒后超时,以防万一运行缓慢/损坏.如果您的FT搜索跨多个索引,则非常有用.

按以下方式调用:

EXECUTE [dbo].[WaitForFullTextIndexing] 'MY_TABLE,ALTERNATE_NAMES,TAG_GROUP_VALUES,TAG_GROUPS,FIELD_OPTION';
Run Code Online (Sandbox Code Playgroud)

来源:

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
Run Code Online (Sandbox Code Playgroud)

dbo.split是一个表值函数,现在每个人都必须拥有它,它将分隔符上的字符串拆分为临时表:

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
Run Code Online (Sandbox Code Playgroud)


Gar*_*wen 8

谢谢丹尼尔,你的回答让我走上正轨.

我实际上使用以下T-SQL语句来询问全文索引的填充状态是否为空闲:

SELECT OBJECTPROPERTY(object_id('v_doc_desc_de'), 'TableFulltextPopulateStatus')
Run Code Online (Sandbox Code Playgroud)

'v_doc_desc_de'是我们索引的数据库视图的名称.

如果人口状态不是空闲,我会等待几秒钟再次询问,直到它处于空闲状态.重要的是在检查之间等待一小段时间,以确保通过不断检查人口状态来减缓全文填充.

MSDN文档指出OBJECTPROPERTYEX函数(在表级别),建议在FULLTEXTCATALOGPROPERTY财产"PopulateStatus"语句.它陈述如下:

SQL Server的未来版本中将删除以下属性:LogSize和PopulateStatus.避免在新的开发工作中使用这些属性,并计划修改当前使用其中任何属性的应用程序.