提高 SQL Server 中全文查询的性能

本文提供了一种方法来改进在 SQL Server 中使用全文谓词的查询的性能。

原始产品版本: SQL Server
原始 KB 数: 2549443

总结

本文介绍了提高使用全文搜索谓词(如 CONTAINSCONTAINSTABLE)以及筛选数据的 sql Server 查询Microsoft性能的方法。 例如,此方法可提高以下查询的性能:

SELECT * FROM dbo.ftTest WHERE CONTAINS(TextData, '"keyword"') AND CDate > @date

此方法允许你设计查询、表架构和全文索引,这样全文搜索引擎就可以筛选出结果,然后再发送到关系引擎。 因此,关系引擎不必筛选大型数据集。

详细信息

创建全文搜索查询时,影响查询性能的原则因素是全文搜索引擎在将剩余数据发送到关系引擎之前必须处理的数据数量。 在 SQL Server 中,可以通过提前筛选出行来改进查询的性能,以减少以后必须处理的行数。

本文所描述的方法使用 Table-Valued 函数 (TVF) 提前过滤行,以减少后续需要处理的行数。

例如,以下查询计划返回与搜索字符串匹配 CONTAINS 的131051行。 此外,计划的联接运算符使用索引查找执行其他筛选。

Rows StmtText
-------------------- ----------------------------------------------------------------------------------------
1167 SELECT CDate, ID FROM dbo.fttest WHERE contains (c2, '"create"') AND CDate> '08/05/2019'

1167 |--Merge Join(Left Semi Join, MERGE:([FTSdb].[dbo].[fttest].[ID])=(FulltextMatch.[docid]), RESIDUA
5858 |--Sort(ORDER BY:([FTSdb].[dbo].[fttest].[ID] ASC))
5858 | |--Clustered Index Seek(OBJECT:([FTSdb].[dbo].[fttest].[clidx1]), SEEK:([FTSdb].[
131051 |--Table-valued function

但是,如果查询包含全文唯一索引键列作为谓词,则全文搜索引擎可以使用谓词在全文级别筛选结果。 在这种情况下,TVF 在应用其他筛选之前返回的数据量要小得多。 例如,以下查询指定了必须与 c2 条件匹配的五个值,TVF 仅返回与五个值匹配的结果:

Rows StmtText
-------------------------------------------------------------------------------------------------------------------------------------------
5 SELECT CDate, ID FROM dbo.fttest WHERE contains (c2, '"create"') AND CDate > '08/05/2019' AND ID IN ( 654051, 644051, 649106, 465, 105)

5 |--Nested Loops(Left Semi Join, OUTER REFERENCES:([FTSdb].[dbo].[fttest].[ID]))
5 |--Index Seek(OBJECT:([FTSdb].[dbo].[fttest].[idx1]), SEEK:([FTSdb].[dbo].[fttest].[ID]=(105) OR ...
5 |--Table-valued function

全文搜索引擎向下推送唯一索引键使用的值是以下方法的基础。

如果谓词包含数据类型列,则可以在唯一 DateTime 索引键列中包括日期信息,以便只返回与此谓词匹配的行。 为此,必须在键列中以逻辑方式合并日期信息。 但是,可能还必须更改使用查询的键列数据类型和应用程序。

若要实现该方法,请将全文唯一键 ID 的数据类型更改为 BIGINT。 密钥 ID 的前 4 个字节捕获日期列中的年份、月份和日期值,最后 4 个字节保持不变。 例如,密钥 ID 的第一个字节可以引用年份,下一个字节可以引用月份,最后 2 个字节可以引用日期。 应用程序必须适应此数据类型更改。

然后,将范围谓词转换为密钥 ID 上的谓词。 例如,范围 x < CDate < y 谓词可以转换为 (x*2^32 < ID < y*2^32) 谓词。 由于翻译的谓词是全文键的谓词,因此谓词将向下推送到全文流式处理表值函数(STVF)。 此行为有效地在日期范围内执行搜索。