【问题标题】:Short circuiting in sql server with full text search predicatessql server中的短路与全文搜索谓词
【发布时间】:2015-02-05 06:48:45
【问题描述】:

我是t-sql和sql server的新手,有一个关于短路和全文搜索的问题。 假设我有这样的声明:

SELECT * 
FROM t1 
LEFT JOIN t2
ON t1.Id = t2.Id
WHERE contains(t1.Field1,@word) or contains(t2.Field2,@word)

我的想法是检查 t1.Field1 是否包含@word,如果为真 - 无需检查第二个条件,如果为假 - 检查第二个包含。但我已经明白,这不起作用,并且此查询执行包含并花费时间进行不必要的工作。所以我想问我怎样才能避免执行这些不必要的谓词。

【问题讨论】:

  • 你有什么证据表明它正在做额外的工作?我会将其更改为“and (contains(t1.Field1,@word) 或 contains(t2.Field2,@word))”

标签: sql-server tsql full-text-search


【解决方案1】:

我曾经有过类似的问题,偶然看到了 Mladen Prajdić 的一篇有见地的文章:

http://weblogs.sqlteam.com/mladenp/archive/2008/02/25/How-SQL-Server-short-circuits-WHERE-condition-evaluation.aspx

简而言之,T-SQL 不支持像 C# 等命令式语言那样短路布尔值,因为无法保证评估谓词的顺序。

实现谓词有序评估的唯一方法是使用 CASE WHEN 构造,它从左到右评估谓词并在第一个为真时停止。如果潜在的性能提升是合理的,您可以将查询重写为:

SELECT * 
FROM t1 
LEFT JOIN t2
ON t1.Id = t2.Id
WHERE 
   Case
   When contains(t1.Field1,@word) Then 1
   When contains(t2.Field2,@word) Then 1
   Else 0
   = 1

在某些情况下,这种方法可能有用。但是,我不建议将其作为常见做法,因为它会降低代码的可读性,甚至会降低性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    • 2020-05-31
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多