Mysql “执行”;插入。。。“关于重复密钥更新”;相比于;更新;

Mysql “执行”;插入。。。“关于重复密钥更新”;相比于;更新;,mysql,Mysql,99%的时间只需一次更新,但不到0.01%的时间需要在同一个键上插入。这可以写成一个INSERT。。。关于重复密钥更新,但就性能而言,我应该吗 问题基本上是如果INSERT。。。在重复密钥更新时s预计比MySQL中的UPDATEs慢 要演示的一些代码: 使用更新编码 UPDATE foo SET seq = @new_seq WHERE id = X AND seq = @prev_seq; IF rows_changed = 0 THEN INSERT INTO foo (id, s

99%的时间只需一次
更新
,但不到0.01%的时间需要在同一个键上插入
。这可以写成一个
INSERT。。。关于重复密钥更新
,但就性能而言,我应该吗

问题基本上是如果
INSERT。。。在重复密钥更新时
s预计比MySQL中的
UPDATE
s慢

要演示的一些代码:

使用更新编码

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
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
强烈建议您自己对其进行基准测试。 这很容易做到,而且更有说服力


理论上,我不认为
插入。。。重复键更新时
会将您向下拖动

案例1:更新没有索引的表 在这种情况下,
UPDATE
操作将锁定此表中的所有记录。但是
INSERT
操作仅锁定间隙(插入意图锁)和插入的记录

因为您使用了
INSERT。。。在这里的重复键更新
中,更有可能是使用索引更新表

案例2:使用索引更新表 假设您正在使用主键更新表。
UPDATE
INSERT
在B+树中查找特定记录的成本相同。对于
INSERT也一样。。。在重复密钥更新时
。所以没有理由插入。。。在重复密钥更新时
会慢得多


而且,
INSERT。。。在重复密钥更新时,如果发现重复密钥,则不会添加插入意图锁。它只会在表上添加一个
IX
锁,在特定记录上添加一个
X
锁,就像
UPDATE
一样。

您可以对它们进行基准测试,但第一个应该更有效。在您的案例中更是如此,因为您只需要在0.01%的案例中插入
INSERT
。然而,比两者都好的方法是知道何时使用
UPDATE
和何时使用
INSERT
,并且永远不要在错误的时间使用它们中的任何一个。案例2听起来很合理,给了我继续进行下去的信心。尽管如此,我还是进行了基准测试,对于10000次批量更新,两种方法都需要大约3秒的时间,所以没有明显的差异。案例1似乎在比较语义上不同的东西。确切地说,我只想列出所有的情况,案例2就是你在这里面对的。