61

我希望能够使用“replace into”语句更新相同模式的表。最后,我需要能够使用可能已更改的值来更新一个大表。

这是我用来开始的查询:

REPLACE INTO table_name
(visual, inspection_status, inspector_name, gelpak_name, gelpak_location),
VALUES (3, 'Partially Inspected', 'Me', 'GP1234', 'A01');

我不明白的是数据库引擎如何知道什么是重复行,什么不是?这些数据非常重要,我不能冒数据被损坏的风险。是否像“如果列出的所有列都具有相同的值,则它是重复行”一样简单?

我只是想找出一种有效的方法来做到这一点,这样我就可以在一分钟内更新 > 45,000 行。

4

3 回答 3

98

正如文档所说:

REPLACE 的工作方式与 INSERT 完全相同,只是如果表中的旧行与 PRIMARY KEY 或 UNIQUE 索引的新行具有相同的值,则在插入新行之前删除旧行。

于 2013-11-06T19:13:31.367 回答
28

REPLACE确实工作起来很像INSERT只是覆盖具有相同PRIMARY KEYUNIQUE索引的记录,但是要小心。

Shlomi Noach 写了在REPLACE INTO 这里使用的问题:

但是像我这样心软的人应该意识到以下几点:这是一个重量级的解决方案。就易用性而言,这可能正是您所寻找的,但事实是,在重复键上,会执行 DELETE 和 INSERT,这需要仔细研究。

每当删除一行时,所有索引都需要更新,最重要的是 PRIMARY KEY。当插入新行时,也会发生同样的情况。特别是在 InnoDB 表上(因为它们的集群性质),这意味着很多开销。指数的重组是一项昂贵的操作。索引节点可能需要在 DELETE 时合并。由于 INSERT 可能需要拆分节点。在多次 REPLACE INTO 执行之后,如果您使用了 SELECT/UPDATE 或 INSERT INTO ... ON DUPLICATE KEY,那么您的索引很可能比原本的索引更加碎片化

此外,还有“好吧,如果行不存在,我们创建它。如果它存在,它只是得到更新”的概念。这是错误的。该行不仅被更新,而且被完全删除。问题是,如果该表上有一个 PRIMARY KEY,并且 REPLACE INTO 没有为 PRIMARY KEY 指定一个值(例如,它是一个 AUTO_INCREMENT 列),那么新行会得到一个不同的值,这可能不是什么你在寻找行为方面。

REPLACE INTO 的许多用途无意更改 PRIMARY KEY(或其他 UNIQUE KEY)值。在这种情况下,最好不要管它。在我见过的生产系统上,将 REPLACE INTO 更改为 INSERT INTO ... ON DPLICATE KEY 会导致吞吐量增加十倍(以每秒查询数衡量)以及 IO 操作和平均负载的急剧下降。

总之,它REPLACE INTO 可能适合您的实现,但您可能会发现使用它更合适(并且风险更小)INSERT ... ON DUPLICATE KEY UPDATE

于 2018-01-15T18:47:14.343 回答
0

或类似的东西:

insert ignore tbl1 (select * from tbl2);

UPDATE
        `tbl1` AS `dest`,
        (SELECT * FROM tbl2) AS `src`
    SET
       dest.field=src.field,
       dest.field=if (length(src.field)>0,src.field,dest.field) /* or anything like that*/
    WHERE
        `dest`.id = `src`.id; 
于 2019-07-26T12:56:04.083 回答