我目前首先在MS Access Table上向MySQL表添加数十万行数据。
我首先尝试使用MS Access,花了不到40秒。 然后我尝试使用相同的源和相同的表结构到MySQL,它花了6分40秒。那是慢了1000%!!!
数据库服务器具有更好的性能是神话吗?
答案 0 :(得分:3)
执行数以千计的独立INSERT将会非常缓慢地运行。由于MySQL是一个多用户的事务性数据库,因此在每次查询期间都会有比Access更多的事情。 SQL Server上的每个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;
在mysql.com网站上阅读有关PREPARE的更多信息。
将几个(或几百个)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。
不要进行数千次INSERTS,而是批量上传数据。如果您的数据位于分隔文件(例如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页面的链接。
答案 1 :(得分:2)
通常,数据库最重要的性能方面不是插入数据的速度有多快,而是查询数据的速度有多快。我认为MySQL具有比MS Access更强大的优化器,可以更好地利用索引。这方面的一个例子是loose index scan,它可以为某些类型的查询提供10倍或更高的速度。
此外,用于插入数据的方法可能会影响插入所需的时间。例如,与许多单独的插入语句相比,使用批量插入通常会更快。在插入时禁用索引并在之后再次启用它们可以提高性能。
答案 2 :(得分:1)
MySQL是否提供任何SQL跟踪工具,以便您可以看到Access正在发送它?根据我通过ODBC使用Access与SQL Server的经验,我可以告诉你,Jet通过批量插入做出了一些看似奇怪的决定。它的作用是为每条记录发送一个插入,而不是为所有记录发送批量插入。这使它大大减慢,但它确实意味着它不能将SQL Server与长更新(以及相应的表锁等)捆绑在一起。
从插入的角度来看,它是愚蠢的,但从成为一个好的客户端/服务器公民的角度来说是聪明的 - 它允许SQL Server决定如何序列化所请求的命令并将它们与来自其他用户的命令交错。这意味着锁定比在批量插入时更短。
使用SQL Server,您可以使用ADO执行此操作并强制它以批处理方式处理插入。我不知道有没有办法用MySQL做到这一点。
要考虑的一件事:
如果源表和目标表都在MySQL中,则直通查询应该使其完全由MySQL处理。