99% 的情况下,单个就足够了,但不到 0.01% 的情况下,我需要在同一键上UPDATE跟进。INSERT这可以写成一个单一的INSERT ... ON DUPLICATE KEY UPDATE,但就性能而言,我应该吗?
问题基本上是INSERT ... ON DUPLICATE KEY UPDATEs 是否预计比UPDATEMySQL 中的 s 慢。
一些代码来演示:
代码使用UPDATE
UPDATE foo SET seq = @new_seq WHERE id = X AND seq = @prev_seq;
IF rows_changed = 0 THEN
INSERT INTO foo (id, seq) VALUES (X, @new_seq)
IF <duplicate key error> THEN
-- handle collusion
END IF
END IF
Run Code Online (Sandbox Code Playgroud)
代码使用INSERT ... ON DUPLICATE KEY UPDATE
INSERT INTO foo (id, seq) VALUES (X, @new_seq)
ON DUPLICATE KEY UPDATE seq = IF(seq = @prev_seq, VALUES(seq), seq)
IF rows_changed = 0 THEN
-- handle collusion
END IF
Run Code Online (Sandbox Code Playgroud)
这很容易做到,而且更有说服力。
从理论上讲,我认为这不会INSERT ... ON DUPLICATE KEY UPDATE拖累你。
在这种情况下,该UPDATE操作将锁定该表中的所有记录。但INSERT操作只锁定一个间隙(Insert Intention Lock)和插入的记录。
由于您在此处使用INSERT ... ON DUPLICATE KEY UPDATE,因此您更有可能正在使用索引更新表。
假设您正在使用主键更新表。和UPDATE都INSERT将支付相同的成本来查找 B+ 树中的特定记录。对于 也是一样INSERT ... ON DUPLICATE KEY UPDATE。所以没有理由INSERT ... ON DUPLICATE KEY UPDATE会慢很多。
此外,INSERT ... ON DUPLICATE KEY UPDATE如果发现重复键,则不会添加插入意向锁。它只会IX在表上加锁,并X在特定记录上加锁,就像这样UPDATE做一样。