如果下面的last_name是NULL,是否會跳過該列上的WHERE比較以提高性能?MySQL並跳過WHERE謂詞
AND (last_name IS NULL OR sp.last_name LIKE CONCAT('%',IFNULL(last_name, ''),'%'))
如果下面的last_name是NULL,是否會跳過該列上的WHERE比較以提高性能?MySQL並跳過WHERE謂詞
AND (last_name IS NULL OR sp.last_name LIKE CONCAT('%',IFNULL(last_name, ''),'%'))
MySQL可以按任意順序自由執行比較。
很可能它會首先執行NULL
檢查,因爲它計算速度更快,但這不能保證。
如果偶然選擇NULL,它會跳過第二個比較正確嗎? – 2012-07-10 16:51:58
出於好奇,你真的試過了你似乎正在避免的更簡單的'WHERE sp.last_name LIKE CONCAT('%',last_name,'%'))嗎?它*可能會證明它不如你擔心的那麼慢...... – 2012-07-10 16:58:43
我有,並且查詢時間略有增加。 – 2012-07-10 17:07:05
據我所知,這是事實,它將包括行而不評估後者的表達式。然而,這可能(應該)使用已知的數據集進行測試,通過使後者表達式創建副作用(例如遞增計數器)並在針對last_name列中只有NULL的數據集運行之前和之後檢查計數器。
對於好奇:
+------+
| 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一次。
試試這個:
AND (if(last_name is null,1, sp.last_name
LIKE CONCAT('%',last_name,'%')))
這裏不是'last_name IS NULL OR ...'多餘嗎? – 2012-07-10 16:54:22
「多餘」是什麼意思?我剛剛使用他的代碼 – jcho360 2012-07-10 16:58:06
我的意思是不必要的多餘和不必要的重複。 – 2012-07-10 17:05:19
這就是所謂的 「短路」 的評價。如果你搜索這個,你會發現更多的結果。 – 2012-07-10 17:36:47
我跑了一些可能感興趣的測試,結果如下我的答案。 – 2012-07-10 23:43:42
我看到很有意思。 – 2012-07-11 17:27:29