Mysql

MySQL (InnoDB) UPDATE SET 性能與 WHERE AND 子句中的值

  • November 14, 2013

如果執行 UPDATE 查詢,其中 SET 的值也是 WHERE 子句的一部分,以對正在設置的列的值的附加 AND 語句的形式,是否有顯著的性能提升?以這種方式更新一組記錄還有其他好處嗎?

例如,

UPDATE table1 SET value1='foo' WHERE value2='bar' AND value1 != 'foo';

對比

UPDATE table1 SET value1='foo' WHERE value2='bar';

一個更簡潔的例子:

+--------------------+-------------------------------------------------+------+-----+---------+----------------+
| Field              | Type                                            | Null | Key | Default | Extra          |
+--------------------+-------------------------------------------------+------+-----+---------+----------------+
| pk_id              | int(10) unsigned                                | NO   | PRI | NULL    | auto_increment | 
| user_id            | int(11)                                         | YES  |     | NULL    |                | 
| status             | enum('unread','accepted','deleted')             | YES  |     | NULL    |                | 
| processed_datetime | datetime                                        | YES  |     | NULL    |                | 
| some_column        | varchar(255)                                    | YES  |     | NULL    |                | 
+--------------------+-------------------------------------------------+------+-----+---------+----------------+

…與另一個範例查詢:

UPDATE table1 SET status = "accepted", processed_datetime = NOW() WHERE pk_id = 1234 AND user_id = 5678 AND status != "accepted"

(注意:這不是我的程式碼/架構,而是我正在使用的其他人的程式碼/架構)

這在很大程度上取決於UPDATE.

例如,如果該表有 1,000,000 行value1 = 'foo'且只有 1 行,value1 <> 'foo'UPDATE table1 SET value1='foo' WHERE value2='bar' AND value1 <> 'foo';實際上只會更新一行。而 UPDATE table1 SET value1='foo' WHERE value2='bar';將更新 1,000,001 行。

如果您談論的是只有兩行的表,則差異完全可以忽略不計。

如果您使用的是 SQL Server 並且有一個過濾索引,WHERE value2 = 'bar' AND value1 <> 'foo'那麼UPDATE table1 SET value1='foo' WHERE value2='bar' AND value1 <> 'foo';很可能會使用索引而不是掃描整個表。

在我看來,有額外的條件WHERE在查詢中沒有什麼區別,比如UPDATE table1 SET value1='foo' WHERE value2='bar' AND value1 != 'foo';.

然而,UPDATE table1 SET value1='foo' WHERE value2='bar' AND value1 = 'bar1';不一樣。首先,如果你有一個索引,bar1它將被使用,因為UPDATE已經讀取組件並且它必須首先定位記錄。其次,它可以在一定程度上防止“失去更新”問題,在我看來,它就像一種樂觀鎖定。

引用自:https://dba.stackexchange.com/questions/53267