从MySQL中的临时表替换表中数据的最快方法

时间:2017-08-19 21:16:25

标签: mysql bulk-load

我需要"更新"我从外部源接收的一些表数据(每次我收到"所有"数据,某些记录更新的某些字段)。 没有唯一的字段或字段组合,因此我认为最好的方法是每次都清除DB中的所有数据并再次写入所有(现在更新的)数据。最多有1000条记录(永远不会超过这些记录),每条记录大约有15个短字段:文本,数字,日期时间。我将它写入远程数据库(因此,它很慢)。

目前我正在做:

delete from `table` where `date_dt` > ?

然后为每一行

INSERT INTO `table` ( `field_0`,`field_1`,... ) VALUES (?,?,...)

它不仅速度慢,而且在我还在插入时,最终用户可能无法看到完整的数据。

我想我能做到:

CREATE TEMPORARY TABLE `temp_table` ( ... ); -- same structure as in main table
INSERT INTO `temp_table` ( `field_0`,`field_1`,... ) VALUES (?,?,...)   -- repeat 1000x

START TRANSACTION;
DELETE FROM `table`;
INSERT INTO `table` SELECT * FROM `temp_table`;
DROP `temp_table`;
COMMIT;

这有什么意义吗?什么是解决这个问题的更好方法?

使用数据填充临时表的速度并不重要,但在主表中填入数据是(因此用户不会看到不完整的数据,或者他们所做的时间很短)。

1 个答案:

答案 0 :(得分:0)

mysqlimport --delete将首先截断表格,然后从CSV文件加载外部数据。它的运行速度比一次插入一行快几倍。

请参阅https://dev.mysql.com/doc/refman/5.7/en/mysqlimport.html

我在2017年4月做了关于MySQL批量数据加载性能的演示: https://www.slideshare.net/billkarwin/load-data-fast

P.S。:如果您有MySQL复制环境,请不要使用临时表解决方案。这是一种众所周知的破坏复制的方法。如果从属设备在创建临时表和从临时表读取的INSERT ... SELECT之间重新启动,则从属设备将发现临时表已消失,这将导致错误并停止复制。这似乎不太可能,但最终确实会发生。