我有一个SQL转储,它很大(411 MB),在服务器A上导入花了10分钟,在我的工作站B上的相同导入,估计(pipeviewer)要导入8小时(它在40分钟内导入了31 MB) )
所以这要慢53倍。

规格:

Server A:
   MySQL Version: 5.5.30-1.1 (Debian)
   2 GB RAM
   1 core QEMU Virtual CPU version 1.0 - cpu MHz: 3400.020

Workstation B: 
   MySQL Version: 5.5.41-MariaDB-1ubuntu0.14.04.1
   14 GB RAM
   4 cores Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz - cpu MHz: 1600.000


mysql / maria配置是常用配置。

我昨天切换到工作站上的MariaDB,但是在MariaDB之前,统计数据甚至更糟。
最大的问题是:性能如何降低53倍?我不能这样工作:-(

我的导入命令:

pv sql/master.sql | mysql -h'localhost' -u'root' -p'root' 'master'


iostat -xm 5

服务器A:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
      17,43    0,00   30,28   51,85    0,00    0,44

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00   254,03    0,00 1305,45     0,00     6,09     9,56     0,78    0,60    0,00    0,60   0,57  74,25


工作站B:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
       7,32    0,00    3,22    5,03    0,00   84,42

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00     1,40    0,80  172,40     0,00     0,56     6,72     1,17    6,75   12,00    6,72   5,40  93,52


dd if=/dev/zero of=tempfile bs=1M count=1024 conv=fdatasync,notrunc

服务器A:

1073741824 bytes (1,1 GB) copied, 18,6947 s, 57,4 MB/s


工作站B:

1073741824 bytes (1,1 GB) copied, 8,95646 s, 120 MB/s


评论

您能描述一下您想如何导入数据库吗? (您的具体mysql语句是什么)“显示进程列表”是什么?说?您是否看过该过程在使用strace进行具体操作?如果您的计算机可能正在交换,还可以看看吗?

我编辑了问题。

InnoDB?每台机器上的innodb_buffer_pool_size的值是什么?

#1 楼

这个答案大大加快了一切:

https://stackoverflow.com/a/2167641/292408

我只是

SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;


开头,

COMMIT;
SET unique_checks=1;
SET foreign_key_checks=1;


结尾。

现在花了3分钟。

(由@andreasemer通过Twitter提供)

评论


很棒的把戏。我需要知道的一点是,这样做有副作用吗?

–达摩萨普特拉
17年11月27日在7:58

如果您的数据已损坏,则导入后可能无法满足外键约束。

– Alex
17年11月27日在12:21

伟大的工作。您从字面上救了我几个小时。

– Jafo
18年1月23日在22:49

没有为我提高性能。没有它,它是23分钟,之后是23分钟(3GB .sql文件)。

–约书亚·品特(Joshua Pinter)
19年12月6日,下午3:58

#2 楼

补充上面的内容...我的转储文件已经由类似以下内容的文件自动生成:

mysqldump my_db > db-dump-file.sql


我想自动执行此导入操作,因此我在自己的文件中创建了两个文件名为default-start-import.sqldefault-end-import.sql的计算机及其内容为default-start-import.sql:

SET autocommit=0;


和default-end-import.sql:

COMMIT;
SET autocommit=1;


,我运行的脚本是这样的;

cat default-start-import.sql db-dump-file.sql default-end-import.sql | mysql my_other_db


相同的命令,但更易于阅读: />
cat default-start-import.sql \
    db-dump-file.sql \
    default-end-import.sql \
| mysql my_other_db


在这种情况下,cat用于在将这些文件发送到管道之前对其进行串联。我认为所有文件都必须以换行符结尾(如果从文本编辑器中查看,文件末尾为空行)是很重要的,这样cat命令就不会在文件之间合并行。

导入工作正常,由于启用和禁用自动提交功能的改进,我还没有测试它是否实际上更快,但是如果这样做会使速度更快,那么此额外步骤将使事情变得更容易。

#3 楼

我已经尝试过--compressSET autocommit=0;,但是它们的作用很小。

我发现将多个INSERT INTO ...语句转换为一个具有多个VALUES(...), (...)的大型语句可以大大提高速度。

我正在通过WAN上的SSL使用mysql。远程MySQL数据库托管在Amazon上。

9列和2,100行:


2,100个单独的INSERT语句:82s
2个合并的INSERT语句:<1s

有7列和42,000行:


42,000个单独的INSERT语句:1,740s
42个合并的INSERT语句:105s

因此,取决于生成数据库转储的工具(或更具体而言,INSERT语句的格式),速度可能会受到影响。在我的测试中,超过60%的数据因此也可以节省I / O。

警告:.sql的这项技术存在物理上的局限性,对于那些需要可移植性的人来说... SQL Server似乎是一次只能限制为1,000行。

仍然,一次执行1,000行以达到42,000行仍然可以提高1,657%!

#4 楼

为了补充上述亚历克斯的回答,您还可以保存和恢复默认变量,而不仅仅是在之后盲目地将它们设置为1。在大多数情况下,将其设置为1是您想要的,但以防万一,这是一种将其设置回导入之前的状态的方法:
PRE导入:
SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, AUTOCOMMIT = 0;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS = 0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0;

POST导入:
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
SET AUTOCOMMIT = @OLD_AUTOCOMMIT;
COMMIT;