我希望能够使用“替换为”语句更新同一模式的表。最后,我需要能够使用可能已更改的值更新大型表。
以下是我开始使用的查询:
REPLACE INTO table_name
(visual, inspection_status, inspector_name, gelpak_name, gelpak_location),
VALUES (3, 'Partially Inspected', 'Me', 'GP1234', 'A01');
我不明白的是数据库引擎如何知道什么是重复行?什么不是?这些数据非常重要,我不能冒数据被破坏的风险。它是否像“如果列出的所有列具有相同的值,它是一个重复的行”一样简单?
我只想弄清楚这样做的有效方法,以便我可以更新>一分钟内45,000行。
答案 0 :(得分:74)
正如documentation所说:
REPLACE的工作原理与INSERT完全相同,只是如果表中的旧行与PRIMARY KEY或UNIQUE索引的新行具有相同的值,则在插入新行之前删除旧行。
答案 1 :(得分:13)
REPLACE
的确非常像INSERT
,它只会覆盖具有相同PRIMARY KEY
或UNIQUE
索引的记录,但请注意。
Shlomi Noach撰写了使用REPLACE INTO
here时遇到的问题:
但是,作为我自己的弱心人应该注意以下事项:这是一个重量级的解决方案。它可能正是您在易用性方面所寻求的,但事实是在重复键上执行DELETE和INSERT,这需要仔细研究。
每当删除一行时,所有索引都需要更新,最重要的是PRIMARY KEY。插入新行时,会发生同样的情况。特别是在InnoDB表上(由于它们的集群特性),这意味着很多开销。指数的重组是一项昂贵的操作。可能需要在DELETE时合并索引节点。由于INSERT,节点可能需要拆分。经过多次REPLACE INTO执行后,如果您使用SELECT / UPDATE或INSERT INTO ...在DUPLICATE KEY上,您的索引最有可能比它本来更碎片
此外,还有"嗯,如果行不在那里,我们就会创建它。如果它在那里,它只是更新"。这是错误的。该行不会更新,它会被完全删除。问题是,如果该表上有一个PRIMARY KEY,并且REPLACE INTO没有为PRIMARY KEY指定一个值(例如,它是一个AUTO_INCREMENT列),则新行获得不同的值,这可能不是你在行为方面所寻求的。
REPLACE INTO的许多用法无意更改PRIMARY KEY(或其他UNIQUE KEY)值。在那种情况下,最好不要单独留下。在我已经看到的生产系统上,将REPLACE INTO更改为INSERT INTO ... ON DPLICATE KEY导致吞吐量增加10倍(以每秒查询数衡量)并且IO操作和负载平均值急剧下降。 / p>
总之,REPLACE INTO
可能适合您的实施,但您可能会发现使用INSERT ... ON DUPLICATE KEY UPDATE
更合适(风险更小)。
答案 2 :(得分: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;