改进全文索引的性能

硬件资源(例如内存、磁盘速度、CPU 速度和计算机体系结构)会影响全文索引和全文查询的性能。

性能问题的常见原因

导致全文索引性能降低的主要原因是硬件资源的限制:

  • 如果筛选器守护程序主机进程 (fdhost.exe) 或 SQL Server 进程 (sqlservr.exe) 的 CPU 使用率接近 100%,则 CPU 会成为瓶颈。

  • 如果平均磁盘等待队列长度是磁盘头数量的两倍以上,则磁盘将成为瓶颈。 主要的解决方法是创建独立于 SQL Server 数据库文件和日志的全文目录。 将日志、数据库文件和全文目录分别放在不同的磁盘上。 购买运行速度更快的磁盘和使用 RAID 也能帮助改善索引性能。

  • 如果物理内存不足(3GB 限制),则内存可能是瓶颈。 物理内存限制可能存在于所有系统上,而在 32 位系统上,虚拟内存压力可导致全文索引速度降低。

    注意

    从 SQL Server 2008 开始,全文引擎可以使用 AWE 内存,因为全文引擎是sqlservr.exe的一部分。

如果系统没有硬件瓶颈,则全文搜索的索引性能主要取决于以下因素:

  • SQL Server 创建全文批次花费的时间。

  • 筛选器后台程序能以多快的速度处理这些批次。

注意

与完全填充不同,增量、手动和自动更改跟踪填充的设计目的并不是为了最大程度地利用硬件资源以获得更高速度。 因此,这些优化建议可能不会增强全文索引的性能。

填充完成后,将触发最终的合并过程,以便将索引碎片合并为一个主全文索引。 由于只需要查询主索引而不需要查询大量索引碎片,因此这将提高查询性能,并且可以使用更好的计分统计信息来得出相关性排名。 请注意,由于合并索引碎片时必须读取和写入大量数据,所以主合并可能会耗费大量 I/O,但它不会阻塞传入的查询。

重要

对大量数据进行主合并会创建一个长时间运行的事务,在检查点期间延迟事务日志的截断。 在这种情况下,事务日志可能会在完整恢复模式下显著增长。 作为最佳做法,在使用完整恢复模式的数据库中重新组织较大的全文索引之前,应确保事务日志中包含足够的空间用于长时间运行的事务。 有关详细信息,请参阅 管理事务日志文件的大小

优化全文索引的性能

若要最大限度地提高全文索引的性能,请实施下列最佳做法:

  • 若要将所有处理器或核心数设置为最大值,请将 “sp_configuremax full-text crawl ranges设置为系统上的 CPU 数。 有关此配置选项的信息,请参阅 max full-text crawl range 服务器配置选项

  • 请确保基表具有聚集索引。 对聚集索引的第一列使用整数数据类型。 避免在聚集索引的第一列使用 GUID。 对聚集索引执行多范围填充可以产生最高的填充速度。 我们建议充当全文键的列采用整数数据类型。

  • 使用 UPDATE STATISTICS 语句更新基表的统计信息。 更重要的是,更新聚集索引或全文键的统计信息以进行完全填充。 这有助于多范围填充在表上生成良好的分区。

  • 如果要提高增量填充的性能,请对 timestamp 列生成辅助索引。

  • 在大型多 CPU 计算机上执行完全填充之前,建议您通过设置 max server memory 值来暂时限制缓冲池的大小,从而留出足够的内存供 fdhost.exe 进程及操作系统使用。 有关详细信息,请参阅本主题后面的“估计筛选器后台程序宿主进程 (fdhost.exe) 的内存需求量”。

解决完全填充性能问题

若要诊断性能问题,请查看全文爬网日志。 有关爬网日志的信息,请参阅 填充全文索引

如果对完全填充的性能不满意,则建议按顺序执行以下故障排除步骤。

物理内存使用量

在全文填充期间,fdhost.exe 或 sqlservr.exe 的内存有可能不足。 如果全文爬网日志显示 fdhost.exe 正在反复重新启动,或系统返回错误代码 8007008,则意味着这些进程中的某一个进程内存不足。 如果 fdhost.exe 在生成转储(特别是在大型多 CPU 计算机上),则该进程的内存可能不足。

注意

若要获取全文爬网使用的内存缓冲区的信息,请参阅sys.dm_fts_memory_buffers(Transact-SQL)。

可能的原因如下:

  • 如果完全填充期间可用的物理内存量为零,SQL Server 缓冲池可能会占用系统上的大部分物理内存。

    sqlservr.exe 进程试图侵占缓冲池的所有可用内存(最大为配置的最大服务器内存)。 如果分配的 max server memory 过大,fdhost.exe 进程可能会面临内存不足的状况及共享内存分配失败。

    注意

    在多 CPU 计算机上进行全文填充期间,fdhost.exe 或 sqlservr.exe 之间可能出现缓冲池内存争用。 由此造成的共享内存不足会导致批次重试、内存抖动并让 fdhost.exe 进程进行转储。

    可以通过适当地设置 max server memory SQL Server 缓冲池的值来解决此问题。 有关详细信息,请参阅本主题后面的“估计筛选器后台程序宿主进程 (fdhost.exe) 的内存需求量”。 减小用于全文索引的批次大小可能也会有用。

  • 分页问题

    页文件大小不足也会导致 fdhost.exe 或 sqlservr.exe 的内存不足,例如在具有增长受限的较小页文件的系统上。

    如果爬网日志未指示存在任何与内存相关的故障,则很可能是因为过度分页导致性能下降。

估计筛选器后台程序宿主进程 (fdhost.exe) 的内存需求量

进行填充时 fdhost.exe 进程需要的内存量主要取决于它使用的全文爬网范围数、入站共享内存 (ISM) 的大小以及最大 ISM 实例数。

可以使用下面的公式粗略估算筛选器后台程序宿主占用的内存量(以字节为单位):

number_of_crawl_ranges“ism_size”max_outstanding_isms* 2

上面公式中的变量的默认值如下所示:

变量 默认值
number_of_crawl_ranges CPU 数
ism_size x86 计算机为 1 MB

x64 计算机为 4 MB、8 MB 或 16MB,具体取决于物理内存总量
max_outstanding_isms x86 计算机为 25

x64 计算机为 5

下表列出了有关如何估算 fdhost.exe 的内存需求量的准则。 此表中的公式使用以下值:

  • F,它是 fdhost.exe 所需内存的估计值(以 MB 为单位)。

  • T,它是系统中可用物理内存的总量(以 MB 为单位)。

  • M,这是最佳 max server memory 设置。

重要

有关公式的基本信息,请参阅 下面的 123

平台 估算 MB-F 1 中的fdhost.exe内存要求 用于计算最大服务器内存 M 2 的公式
x86 F = 爬网范围 * 50 M =minimum(T 2000**)-F-** 500
x64 F = 爬网范围 * 10 * 8 M = T - F - 500

1 如果正在进行多个完整总体,请分别计算每个填充的fdhost.exe内存要求,例如 F1F2 等。 然后计算 M 为 T -sigma**(_F_i)**

2 500 MB 是系统中其他进程所需的内存的估计值。 如果系统正在执行其他工作,请相应地增加此值。

3.对于 x64 平台,假定ism_size为 8 MB。

示例:估算fdhost.exe的内存要求

此示例针对具有 8GM RAM 和 4 个双核处理器的 AMD64 计算机。 首先计算出 fdhost.exe 所需内存的估计值 -F。 爬网范围数是 8

F = 8*10*8=640

下一个计算获取 M 的最佳值max server memory-。 The total physical memory available on this system in MB-T-is8192.

M = 8192-640-500=7052

示例:设置最大服务器内存

此示例使用 sp_configureRECONFIGURETransact-SQL 语句设置为max server memory在前面的示例中为 M 计算的值: 7052

USE master;  
GO  
EXEC sp_configure 'max server memory', 7052;  
GO  
RECONFIGURE;  
GO  

设置最大服务器内存配置选项

可以降低 CPU 占用率的因素

我们希望当平均 CPU 占用率低于大约 30% 时完全填充的性能不是最佳的。 本节讨论影响 CPU 占用率的一些因素。

  • 长时间等待页面

    若要了解页面等待时间是否很高,请执行以下 Transact-SQL 语句:

    Execute SELECT TOP 10 * FROM sys.dm_os_wait_stats ORDER BY wait_time_ms DESC;  
    

    下表描述了这里需要了解的等待类型。

    等待类型 说明 可能的解决方法
    PAGEIO_LATCH_SH(_EX 或 _UP) 这可能表明存在 IO 瓶颈,在此情况下通常还会发现平均磁盘队列长度很高。 将全文索引移动到其他磁盘上的其他文件组可能有助于减少 IO 瓶颈。
    PAGELATCH_EX(或 _UP) 这可能表明多个正在试图写入相同数据库文件的线程之间存在大量争用现象。 将文件添加到全文索引所在的文件组可能有助于减轻此类争用。

    有关详细信息,请参阅 sys.dm_os_wait_stats (Transact-SQL)

  • 扫描基表的效率很低

    完全填充将扫描基表,以生成批次。 在下列情况下,这样的表扫描可能很低效:

解决索引性能由于筛选器而变慢的问题

在填充全文索引时,全文引擎使用以下两种类型的筛选器:多线程筛选器和单线程筛选器。 有些文档(如 Microsoft Word 文档)使用多线程筛选器进行筛选。 另外一些文档使用单线程筛选器进行筛选,如 Adobe Acrobat 可移植文档格式 (PDF) 文档。

为了安全起见,筛选器是由筛选器后台程序主机进程加载的。 服务器实例对所有多线程筛选器使用多线程进程,并对所有单线程筛选器使用单线程进程。 如果使用多线程筛选器的文档包含使用单线程筛选器的嵌入文档,全文引擎将启动单线程进程以处理嵌入文档。 例如,在遇到包含 PDF 文档的 Word 文档时,全文引擎使用多线程进程来处理 Word 内容,并启动单线程进程以处理 PDF 内容。 但是,单线程筛选器可能无法在此环境中正常工作,并且可能会破坏筛选进程的稳定性。 在某些频繁出现此类嵌入的环境中,它可能会导致筛选进程崩溃。 如果发生这种情况,全文引擎会将任何失败的文档(如包含嵌入 PDF 内容的 Word 文档)重新传送到单线程筛选进程。 如果频繁进行重新传送,将会导致全文索引进程性能下降。

若要解决该问题,必须将容器文档(此处为 Word 文档)的筛选器标记为单线程筛选器。 可以更改筛选器注册表值,以便将给定筛选器标记为单线程筛选器。 若要将筛选器标记为单线程筛选器,需要将筛选器的 ThreadingModel 注册表值设置为 。Apartment Threaded 有关单线程单元的信息,请参阅白皮书 了解和使用 COM 线程模型

另请参阅

“服务器内存”服务器配置选项
max full-text crawl range 服务器配置选项
填充全文索引
创建和管理全文索引
sys.dm_fts_memory_buffers (Transact-SQL)
sys.dm_fts_memory_pools (Transact-SQL)
排除全文索引故障