2014-12-07 54 views
3

我是t-sql和sql server的新手,我有一個關於短路和全文搜索的問題。 假設我有這樣的語句:用全文搜索謂詞在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,如果這是真的 - 不需要檢查第二conditon,如果是假的 - 檢查第二個包含。但我已經明白,這不起作用,並且此查詢執行包含並花費時間來處理不必要的工作。所以我想問如何避免執行這些不必要的謂詞。

+1

你有什麼證據證明它正在做額外的工作?我會將其改爲「和(包含(t1.Field1,@ word)或包含(t2.Field2,@ word))」 – Paparazzi 2014-12-08 19:32:16

+1

[SQL Server中的OR操作符短路](http:// stackoverflow。 COM /問題/ 11219791 /或運營商短路式-SQL服務器) – 2014-12-09 14:14:10

回答

0

我曾經有過一個類似的問題和整個見地的文章姆拉登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 

在某些情況下,此方法可能有用。不過,我不會推薦它作爲常見的做法,因爲它會使代碼變得不易讀,甚至可能會降低性能。