全文搜索入门

SQL Server 中的数据库在默认情况下支持全文索引。不过,若要对表使用全文索引,必须对要使用全文引擎访问的表列设置全文索引功能。

这涉及以下基本步骤:

  1. 创建全文目录来存储全文索引。

    每个全文索引必须属于一个全文目录。您可以为每个全文索引创建一个单独的文本目录,也可以将多个全文索引与给定目录关联起来。

    注意注意

    从 SQL Server 2008 开始,全文目录为虚拟对象且不属于任何文件组。全文目录是表示一组全文索引的逻辑概念。

  2. 对表或索引视图创建全文索引。

    全文索引是一种特殊类型的基于标记的功能性索引,由全文引擎生成和维护。若要对表或视图创建全文搜索,则该表或视图必须具有唯一的、不可为 Null 的单列索引。全文引擎需要使用此唯一索引将表中的每一行映射到一个唯一的可压缩键。全文索引可以包括 char、varchar、nchar、nvarchar、text、ntext、image、xml、varbinary 和 varbinary(max) 列。有关详细信息,请参阅全文索引概述

在了解如何创建全文索引之前,请务必考虑它们与普通 SQL Server 索引的不同之处。下表列出了这些差异。

全文索引

普通 SQL Server 索引

每个表只允许有一个全文索引。

每个表允许有多个普通索引。

将数据添加到全文索引的操作称为“填充”,可以通过计划或特定请求来请求填充,也可以在添加新数据时自动填充。

当插入、更新或删除作为其基础的数据时自动更新。

在同一个数据库内分组为一个或多个全文目录。

不分组。

创建全文索引时的注意事项

本节涵盖以下内容:

  • 选择列语言

  • 选择全文索引的文件组

  • 将全文索引分配到全文目录

  • 将非索引字表与全文索引关联

  • 更新全文索引

选择列语言

有关在选择列语言时要注意的事项的信息,请参阅创建全文索引时选择语言的最佳实践

选择全文索引的文件组

生成全文索引是一个需要大量占用 I/O 的过程(它需要频繁地从 SQL Server 读取数据,然后将筛选后的数据传播到全文索引)。最佳做法是将全文索引置于最适于最大程度地提高 I/O 性能的数据库文件组中,或者将全文索引置于另一个卷的其他文件组中。

如果您非常注重管理的方便性,建议您将表数据和所有关联的全文目录存储在同一文件组中。出于性能的考虑,有时您可能需要将表数据和全文索引置于存储在不同卷上的不同文件组中,以便最大化 I/O 并行度。

将全文索引分配到全文目录

计划表的全文索引在全文目录中的位置非常重要。

建议将具有相同更新特征的表(如更改次数少的与更改次数多的,或者在一天中某个特定时段内频繁更改的表)关联在一起,并置于同一全文目录下。通过设置全文目录填充计划,会使全文索引与表保持同步,且在数据库活动较多时不会对数据库服务器的资源使用产生负面影响。

将表分配到全文目录时,应考虑下列准则:

  • 始终选择可用于全文唯一键的最小唯一索引。(最好是 4 个字节、基于整数的索引。)这将显著减少文件系统中 Microsoft Search 服务所需要的资源。如果主键较大(超过 100 个字节),可以考虑选择表中的另一个唯一索引(或创建另一个唯一索引)来作为全文唯一键。否则,如果全文唯一键的大小超过所允许的最大值(900 个字节),全文填充将无法继续进行。

  • 如果创建索引的表有数百万行,请将该表分配到其自身的全文目录。

  • 考虑要进行全文索引的表中发生的更改量以及总行数。如果要更改的总行数与上次全文填充期间表中出现的行数合起来达到了数百万行,请将该表分配到其自身的全文目录。

将非索引字表与全文索引关联

SQL Server 2008 引入了非索引字表。“非索引字表”是非索引字(也称为“干扰词”)的列表。非索引字表与每个全文索引相关联,因而该非索引字表中的词会应用于对该索引的全文查询。默认情况下,系统非索引字表与新的全文索引相关联。不过,您也可以创建和使用您自己的非索引字表。有关详细信息,请参阅非索引字和非索引字表

例如,下面的 CREATE FULLTEXT STOPLISTTransact-SQL 语句可通过从系统非索引字表进行复制来创建名为 myStoplist3 的新全文非索引字表:

CREATE FULLTEXT STOPLIST myStoplist FROM SYSTEM STOPLIST;
GO

下面的 ALTER FULLTEXT STOPLISTTransact-SQL 语句可更改名为 myStoplist 的非索引字表,首先为西班牙语添加词“en”,再为法语添加词“en”:

ALTER FULLTEXT STOPLIST MyStoplist ADD 'en' LANGUAGE 'Spanish';
ALTER FULLTEXT STOPLIST MyStoplist ADD 'en' LANGUAGE 'French';
GO

更新全文索引

与普通 SQL Server 索引一样,全文索引可以在相关表中的数据修改时自动更新。这是默认行为。另外,还可以手动或在预定的间隔更新全文索引。由于填充全文索引可能极为耗费时间和资源,因此索引更新通常作为异步进程执行,该进程在后台运行,在基表中进行修改后使全文索引保持最新。在基表中进行每次更改后立即更新全文索引可能会占用大量的资源。因此,如果更新/插入/删除操作非常频繁,您可能会发现查询性能有所降低。如果出现这种情况,可以考虑制定一个手动的更改跟踪更新计划,以便按一定的间隔更新大量的更改,从而避免与查询争用资源。

若要监视填充状态,请使用 FULLTEXTCATALOGPROPERTY 或 OBJECTPROPERTYEX 函数。若要获得目录填充状态,请运行以下语句:

SELECT FULLTEXTCATALOGPROPERTY('AdvWksDocFTCat', 'Populatestatus');

通常,如果正在进行完全填充,则返回的结果为 1。

示例:在 AdventureWorks 中设置全文搜索 (Transact-SQL)

下面的示例由两部分组成,首先对 AdventureWorks 数据库创建名为 AdvWksDocFTCat 的全文目录,然后对 AdventureWorks 中的 Document 表创建全文索引。此语句将在安装过程中指定的默认位置创建全文目录。将在默认目录下创建名为 AdvWksDocFTCat 的文件夹。

  1. 为了创建名为 AdvWksDocFTCat 的全文目录,此示例使用了 CREATE FULLTEXT CATALOG 语句:

    USE AdventureWorks;
    GO
    CREATE FULLTEXT CATALOG AdvWksDocFTCat;
    
  2. 在对 Document 表创建全文索引之前,请确保该表具有唯一的、不可为 Null 的单列索引。下面的 CREATE INDEX 语句可对 Document 表的 DocumentID 列创建唯一索引 ui_ukDoc:

    CREATE UNIQUE INDEX ui_ukDoc ON Production.Document(DocumentID);
    
  3. 具有唯一键后,即可使用下面的 CREATE FULLTEXT INDEX 语句对 Document 表创建全文索引。

    CREATE FULLTEXT INDEX ON Production.Document
    (
        Document                         --Full-text index column name 
            TYPE COLUMN FileExtension    --Name of column that contains file type information
            Language 2057                 --2057 is the LCID for British English
    )
    KEY INDEX ui_ukDoc ON AdvWksDocFTCat --Unique index
    WITH CHANGE_TRACKING AUTO            --Population type;
    GO
    

    此示例中定义的 TYPE COLUMN 指定表中的类型列,该列包含“Document”列(为二进制类型)的每一行中文档的类型。此类型列存储给定行中文档的、由用户提供的文件扩展名 —“.doc”、“.xls”等等。全文引擎使用给定行中的文件扩展名调用正确的筛选器,以用于分析该行中的数据。在该筛选器对该行的二进制数据进行分析后,指定的断字符将分析其内容(在此示例中,使用的是英国英语的断字符)。请注意,仅在进行索引时,或者在对全文索引启用了自动更改跟踪的情况下用户在基表中插入或更新列时,才会执行筛选过程。有关详细信息,请参阅全文搜索筛选器

查看有关全文索引的信息

目录视图或动态管理视图

说明

sys.fulltext_index_catalog_usages (Transact-SQL)

对于全文索引引用的每个全文目录,返回与其对应的一行。

sys.fulltext_index_columns (Transact-SQL)

构成全文索引的每列都对应一行。

sys.fulltext_index_fragments (Transact-SQL)

全文索引使用内部表(称为“全文索引片断”)来存储倒排索引数据。可以使用此视图来查询有关这些片断的元数据。在此视图中,每个全文索引片断在每个包含全文索引的表中各占一行。

sys.fulltext_indexes (Transact-SQL)

表对象的每个全文索引对应一行。

sys.dm_fts_index_keywords (Transact-SQL)

返回有关指定表的全文索引内容的信息。

sys.dm_fts_index_keywords_by_document (Transact-SQL)

返回有关指定表的文档级全文索引内容的信息。给定关键字可以出现在几个文档中。

sys.dm_fts_index_population (Transact-SQL)

返回有关当前正在进行的全文索引填充的信息。