我目前正在将数十万行数据添加到一个表中,首先是在 MS Access 表上,然后是在 MySQL 表上。
我首先尝试使用 MS Access,用了不到 40 秒。 然后我尝试使用与 MySQL 完全相同的源和相同的表结构,耗时 6 分 40 秒。那慢了 1000%!!!
那么,数据库服务器具有更好的性能是不是一个神话?
最佳答案
执行数千个独立的 INSERT 将运行得非常慢。由于 MySQL 是一个多用户、事务性数据库,因此在每次查询期间发生的事情比 Access 多得多。 SQL 服务器上的每个 INSERT 操作都经过以下步骤:
- 解码并解析查询。
- 打开表进行写入,必要时建立锁。
- 插入新行。
- 如有必要,更新索引。
- 将表保存到磁盘。
理想情况下,您希望尽可能少地执行步骤 1、2、4 和 5。 MySQL 有一些功能可以帮助您。
准备您的查询
通过准备一个您将要重复使用的查询,您只需执行一次步骤 1。方法如下:
PREPARE myinsert FROM 'INSERT INTO mytable VALUES (?, ?, ?)';
SET @id = 100;
SET @name = 'Joe';
SET @age = 34;
EXECUTE myinsert USING @id, @name, @age;
SET @id = 101;
SET @name = 'Fran';
SET @age = 23;
EXECUTE myinsert USING @id, @name, @age;
# Repeat until done
DEALLOCATE PREPARE myinsert;
阅读更多关于 PREPARE 的信息在 mysql.com 站点。
使用事务
将多个(或数百个)INSERT 组合到一个事务中。服务器每次事务只需执行一次步骤 2、4 和 5。
PREPARE myinsert FROM 'INSERT INTO mytable VALUES (?, ?, ?)';
START TRANSACTION;
SET @id = 100;
SET @name = 'Joe';
SET @age = 34;
EXECUTE myinsert USING @id, @name, @age;
SET @id = 101;
SET @name = 'Fran';
SET @age = 23;
EXECUTE myinsert USING @id, @name, @age;
# Repeat a hundred times
COMMIT;
START TRANSACTION;
SET ...
SET ...
EXECUTE ...;
# Repeat a hundred times
COMMIT;
# Repeat transactions until done
DEALLOCATE PREPARE myinsert;
阅读更多关于 transactions 的信息.
从文件加载表格
与其进行数千次插入,不如批量上传您的数据。如果您的数据位于带分隔符的文件(例如 CSV)中,请使用 LOAD DATA 语句。
LOAD DATA LOCAL INFILE '/full/path/to/file/mydata.csv' INTO TABLE `mytable` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
这是 LOAD DATA 上 MySQL 页面的链接.
关于插入数十万行时,MySQL 与 MS Access 相比非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2797296/