【问题标题】:SQL Server full text search - large querySQL Server 全文搜索 - 大型查询
【发布时间】:2019-09-25 05:54:22
【问题描述】:

我正在使用 SQL Server 2014 中的全文搜索查询在 C# 中编写应用程序。用户需要能够使用包含多达 100 000 个参数的非常大的查询来搜索数据库。例如:

FTS 查询:

SELECT * FROM Client WHERE contains(Name, '"John" OR "Sarah"') 

LIKE 查询:

SELECT * FROM Client WHERE Name in ('John', 'Sarah')

除了 2 个名字,我们有 100 000 个名字。显然,这超出了 SQL 支持的最大查询长度。该数据库包含超过 100 万条记录。在某些情况下,我需要查找以指定字符串开头的客户端名称,这就是为什么 FTS 优于“in”或“like”子句的原因。除了将请求批处理成许多块之外,是否有一些巧妙的绕过方法?有没有比使用 SQL 数据库更好的选择?

我也尝试使用 Lucene.NET 实现搜索,但是为超过 100 万条记录生成索引需要很多小时,这是不可接受的,因为数据将每天同步。

【问题讨论】:

  • 为什么不提取数据表中的所有数据并在数据表行中搜索数据轮询? 1KK 记录选择不应该被执行。之后在 Rows.Itemarray 中搜索您的键
  • 在查询中插入这么多参数通常是个坏主意,这样做会损害您的磁盘、临时数据库、内存并导致数百万次不必要的读取和写入,并可能导致服务器上的数据库碎片化。为什么不能使用 JOINS 将 Client 表连接到 Name 表?我可能理解错了?
  • @Richard 没有名称表。我正在搜索的客户名称来自用户输入。我可以创建一个临时表来存储它们,但 FTS 不能将表列作为搜索参数。
  • @Legion 这可能比批处理请求好一点,我想我会尝试一下,看看它会产生多少内存开销。谢谢!
  • @Andrzej OK 怎么样:在执行搜索时为名称创建一个永久表 (Name [nvarchar],[SearchInstance UNIQUEIDENTIFIER]),生成一个 Guid,将所有名称插入到 Names 表中你的向导。然后使用 Guid 将您的 Client 表连接到 Names 表 WHERE Names.SearchInstance = @Guid。首先有效地将所有参数添加到一个单独的表中,然后加入它以产生结果?如果您认为可以解决,很高兴在完整的答案中解释这一点

标签: c# sql-server entity-framework full-text-search large-query


【解决方案1】:

当使用纯 SQL 时,我建议使用 sp_executesql。这允许您最多传递大约 2100 个参数,每个参数一个。 SQL Server 将能够重新使用该查询的查询计划——无需重新编译——因此速度很快。

通过创建 2100 个名称的批次,您需要 48 个批次;延迟应该相当低。另外,如果您使用多个连接,您可以并行启动它们。

https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view=sql-server-2017

考虑快照隔离或“WITH NOLOCK”以防止数据重新加载期间的延迟。

https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/snapshot-isolation-in-sql-server

https://www.mssqltips.com/sqlservertip/2470/understanding-the-sql-server-nolock-hint/

最后确保您设置了正确的索引并使用 SQL Profiler 检查实际的查询计划以验证是否如此。

【讨论】:

  • 那不需要执行多个 FTS 搜索查询吗?与 IN 查询不同,包含查询将所有搜索参数作为单个字符串接收,不能超过 8000 个字符。
  • 我假设您的语句结构如下:SELECT * FROM Client WHERE Name in (@p1, @p2)
猜你喜欢
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 2010-09-06
  • 2010-11-18
  • 1970-01-01
  • 2012-12-16
  • 2011-03-14
  • 1970-01-01
相关资源
最近更新 更多