Stored procedures 带空参数的SQL Server全文搜索-性能命中

Stored procedures 带空参数的SQL Server全文搜索-性能命中,stored-procedures,sql-server-2012,full-text-search,query-optimization,Stored Procedures,Sql Server 2012,Full Text Search,Query Optimization,我试图在搜索过程中使用Contains()。全文索引已创建并运行。出现此问题的原因是无法对NULL变量或参数使用Contains()调用,它会引发错误 运行此操作需要9秒(传入非空参数): 它立即运行(传入非null参数) 只需在“contains”前面添加额外的“OR”,就完全改变了查询计划。我也尝试过使用“case”语句而不是“OR”,但没有效果,我仍然得到了缓慢的查询 是否有人解决了全文搜索中的空参数问题,或者遇到了我的问题?任何想法都会有帮助,谢谢 我使用SQL Server 2012从

我试图在搜索过程中使用
Contains()
。全文索引已创建并运行。出现此问题的原因是无法对
NULL
变量或参数使用
Contains()
调用,它会引发错误

运行此操作需要9秒(传入非空参数):

它立即运行(传入非null参数)

只需在“contains”前面添加额外的“OR”,就完全改变了查询计划。我也尝试过使用“case”语句而不是“OR”,但没有效果,我仍然得到了缓慢的查询

是否有人解决了全文搜索中的空参数问题,或者遇到了我的问题?任何想法都会有帮助,谢谢


我使用SQL Server 2012

从逻辑角度来看,第一个查询执行时间较长,因为它必须评估两个条件:

@FirstName = '""' 
如果第一个条件失败,大多数情况下都会失败

CONTAINS(m.[fname], @FirstName) 
我的猜测是,在您的表中,您没有任何null或空的名字,这就是结果相同的原因。否则,结果集中会有一些“”作为FirstName

也许你应该试着颠倒顺序,看看是否有什么不同:

WHERE (CONTAINS(m.[fname], @FirstName) OR @FirstName = '""')

您正在检查SQL中bind变量的值。更糟糕的是,您可以使用access谓词或使用access谓词来完成。我不是SQL Server方面的专家,但这通常是一种不好的做法,这样的谓词会导致全表扫描

@FirstName
为空时,若确实需要从表中选择所有值,请在SQL查询之外进行检查

IF @FirstName is null 
  <query-without-CONTAINS>
ELSE
  <query-with-CONTAINS>
如果@FirstName为null
其他的

我相信,在大多数情况下,
@FirstName
不是空的。这样,您将在大多数情况下使用全文索引访问表。无论如何,从表中获取所有行都是一个失败的原因。

这两个查询返回相同的结果?是的,它们返回相同的结果。例如,在这两个查询中,我将“Chris”作为@FirstName传递。两个结果完全相同。第二个查询所做的只是在尝试运行Contains()部分之前检查参数是否为空,以确保未传递NULL,这将导致错误。谢谢您的建议。颠倒顺序的问题是,当我的参数实际为空时,我失去了我的“短路”,然后我会得到一个错误。首先进行检查可以避免调用allI的Contains(),我很困惑。当参数为null时,FirstName不是像IF语句中那样设置为双引号吗?是的,当参数为null时,它设置为双引号。当参数为null时,我希望它返回所有内容;当@FirstName有值时,我希望它使用“Contains()”方法过滤我的结果。然后您可能应该将其设置为空字符串(“”),而不是双引号,并在WHERE子句中省略@FirstName条件。或者,按照那个年轻人的回答做……好的,谢谢,所以我不可能做我想做的事?要进行空检查而不在不需要时运行Contains()?这只是实际过程的一个片段,我有大约8个全文搜索参数,大多数可能是空的。我想我必须使用动态sql来构建一个字符串,然后执行sp_executesql。这基本上可以做到你所说的,而不需要重复太多的代码。基本上,你会一直执行全表扫描,所以我认为这不是一个好主意。仅在需要时添加
的动态SQL才包含
WHERE (CONTAINS(m.[fname], @FirstName) OR @FirstName = '""')
IF @FirstName is null 
  <query-without-CONTAINS>
ELSE
  <query-with-CONTAINS>