與包括可以更有效地有時AND is_leaf=0
查詢。
找到基於主鍵的行時不會有太大的區別。 (索引on (id,is_leaf)
的可用性可能會產生一點差異。)但是,只要MySQL確定沒有要更新的行,它可以採用較短的代碼路徑。
但是,如果缺少謂詞,MySQL將不得不查找該行,獲取行鎖(對於InnoDB),並觸發任何'BEFORE UPDATE FOR EACH ROW'觸發器。然後,MySQL必須檢查是否有任何列值實際上正在更改(請注意,觸發器的執行可能會將一列或多列設置爲不同的值)。如果MySQL檢測到行沒有變化,它可以跳過任何'ON UPDATE'時間戳列的設置,觸發任何'AFTER UPDATE FOR EACH ROW'觸發器,並將受影響的行計數爲零。 (在一個事務的上下文中,一旦確定行沒有被更改,MySQL是否可以釋放行鎖,或者是否在提交或回滾之前,行鎖將繼續保留)。
所以,這兩個語句之間的一個很大的區別在於即使沒有對該行進行實際更改,MySQL也會觸發'FOR EACH ROW'觸發器;但它不會爲WHERE子句排除的行觸發任何'FOR EACH ROW'觸發器。
在簡單的情況下,沒有任何觸發器,我不認爲在性能上有任何可測量的差異。
我個人的偏好是包含額外的謂詞。這確保了不會(InnoDB)意向行鎖被請求或保持,並且不會觸發FOR EACH ROW觸發器。
而且除了行鎖定和觸發執行,只要這兩個聲明是完全一樣的,他們是不是真的。在一般情況下,其中存在一種可能性,即可以is_leaf
包含NULL或鑑於這種語句不是0或1。
其他值至少不:
UPDATE category SET is_leaf=1 WHERE id=9
對於設置is_leaf
等效聲明到1時,它是不是已經等於1,我們實際上需要檢查NULL,比1不同的任何值,如:
UPDATE category SET is_leaf=1 WHERE id=9 AND NOT (is_leaf <=> 1)
考慮當is_leaf
爲空或2會發生什麼,例如,有這個狀態NT:
UPDATE category SET is_leaf=1 WHERE id=9 AND is_leaf=0
當我們設置一個值爲'1'的時候,它已經是'1'了,那麼mysql將會1)檢查它是否會被實際改變,然後決定是否更新它;或2)無論如何更新它,然後監視它是否已被更改?如果這是第一種情況,那麼我認爲這兩個語句完全一樣(除了第二個語句需要更少的行鎖)。 –
代碼路徑部分非常有幫助! –