2

我想将全文搜索用于自动完成服务,这意味着我需要它快速工作!最多两秒。

搜索结果来自不同的表,因此我创建了一个将它们连接在一起的视图。我使用的 SQL 函数是 FREETEXTTABLE()。

查询运行非常缓慢,有时长达 40 秒。

为了优化查询执行时间,我确保基表有一个聚集索引列,它是整数数据类型(而不是 GUID)

我有两个问题:首先,关于如何使全文搜索更快的任何其他想法?(不包括升级硬件...)其次,为什么每次我重建全文目录后,搜索查询都非常快(不到一秒),但仅适用于第一次运行。我第二次运行查询需要几秒钟的时间,而且一切都从那里开始下降......知道为什么会发生这种情况吗?

4

2 回答 2

2

重建目录后第一次查询非常快的原因可能很简单:

当您删除目录并重建它时,必须重建索引,这需要一些时间。如果您在重建完成之前进行查询,他们查询会更快,仅仅是因为数据较少。您还应该注意到,您的查询结果包含较少的行。

因此,只有在索引重建完成测试查询速度才有意义。

以下选择可能会方便检查索引的大小(以及碎片)。当大小停止增长时,索引的重建就完成了;)

-- Compute fragmentation information for all full-text indexes on the database
SELECT c.fulltext_catalog_id, c.name AS fulltext_catalog_name, i.change_tracking_state,
    i.object_id, OBJECT_SCHEMA_NAME(i.object_id) + '.' + OBJECT_NAME(i.object_id) AS object_name,
    f.num_fragments, f.fulltext_mb, f.largest_fragment_mb,
    100.0 * (f.fulltext_mb - f.largest_fragment_mb) / NULLIF(f.fulltext_mb, 0)  AS fulltext_fragmentation_in_percent
FROM sys.fulltext_catalogs c
JOIN sys.fulltext_indexes i
    ON i.fulltext_catalog_id = c.fulltext_catalog_id
JOIN (
    -- Compute fragment data for each table with a full-text index
    SELECT table_id,
        COUNT(*) AS num_fragments,
        CONVERT(DECIMAL(9,2), SUM(data_size/(1024.*1024.))) AS fulltext_mb,
        CONVERT(DECIMAL(9,2), MAX(data_size/(1024.*1024.))) AS largest_fragment_mb
    FROM sys.fulltext_index_fragments
    GROUP BY table_id
) f
    ON f.table_id = i.object_id
于 2016-02-26T06:39:24.963 回答
1

这是一个很好的检查资源。但是,如果您真的想提高性能,则必须考虑升级硬件。(通过将我的数据和全文索引文件移动到单独的读取优化磁盘以及将日志和 tempdb 移动到单独的写入优化磁盘,我看到了显着的性能提升——总共 4 个额外的磁盘加上 1 个用于操作系统和 SQL服务器二进制文件。)

我推荐的其他一些非硬件解决方案:

  1. 自定义内置停用词列表以定义更多停用词,从而减少全文索引的大小。
  2. 更改 tempdb 的文件结构。见这里这里
  3. 如果您的视图对 FREETEXTTABLE 执行超过 1 次调用,则考虑更改您的数据结构,以便视图只需进行 1 次调用。

然而,这些都不是您正在寻找的加快速度的灵丹妙药。我怀疑这里可能还有其他因素(可能是性能不佳的服务器、网络延迟、服务器上的资源争用......)特别是因为你说每次执行全文搜索都会变慢,这与我所看到的相反我的经验。

于 2013-05-30T17:56:51.183 回答