2012-07-10 91 views
2

如果下面的last_name是NULL,是否會跳過該列上的WHERE比較以提高性能?MySQL並跳過WHERE謂詞

AND (last_name IS NULL OR sp.last_name LIKE CONCAT('%',IFNULL(last_name, ''),'%')) 
+1

這就是所謂的 「短路」 的評價。如果你搜索這個,你會發現更多的結果。 – 2012-07-10 17:36:47

+0

我跑了一些可能感興趣的測試,結果如下我的答案。 – 2012-07-10 23:43:42

+0

我看到很有意思。 – 2012-07-11 17:27:29

回答

2

MySQL可以按任意順序自由執行比較。

很可能它會首先執行NULL檢查,因爲它計算速度更快,但這不能保證。

+0

如果偶然選擇NULL,它會跳過第二個比較正確嗎? – 2012-07-10 16:51:58

+0

出於好奇,你真的試過了你似乎正在避免的更簡單的'WHERE sp.last_name LIKE CONCAT('%',last_name,'%'))嗎?它*可能會證明它不如你擔心的那麼慢...... – 2012-07-10 16:58:43

+0

我有,並且查詢時間略有增加。 – 2012-07-10 17:07:05

2

據我所知,這是事實,它將包括行而不評估後者的表達式。然而,這可能(應該)使用已知的數據集進行測試,通過使後者表達式創建副作用(例如遞增計數器)並在針對last_name列中只有NULL的數據集運行之前和之後檢查計數器。

編輯:測試v5.5.25

對於好奇:

+------+ 
| name | 
+------+ 
| NULL | 
+------+ 
| Bill | 
+------+ 

每個查詢下面通過set @foo=0;前面,然後的select @foo;結果示。

SELECT name FROM names WHERE (@foo:[email protected]+1 OR name IS NULL); 
-- 1 (did optimize) - same without parenthesis 

SELECT name FROM names WHERE name IS NULL OR (@foo:[email protected]+1); 
-- 1 (did optimize) 

SELECT name FROM names WHERE (@foo:[email protected]+1) OR name IS NULL; 
-- 2 (did not optimize) 

有趣的是,我無法產生一個更新查詢,而這個查詢並沒有用這種方式進行優化。即不管我如何在where子句中安排兩個表達式,它總是10總是只增加@foo一次。

2

試試這個:

AND (if(last_name is null,1, sp.last_name 
LIKE CONCAT('%',last_name,'%'))) 
+0

這裏不是'last_name IS NULL OR ...'多餘嗎? – 2012-07-10 16:54:22

+0

「多餘」是什麼意思?我剛剛使用他的代碼 – jcho360 2012-07-10 16:58:06

+0

我的意思是不必要的多餘和不必要的重複。 – 2012-07-10 17:05:19