我目前正在创建一个环境来测试应用程序的性能;我正在用MySQL和InnoDB进行测试,以找出哪一种最适合我们.在这个环境中,我们将自动准备数据库(加载现有转储)并为测试工具提供工具.

我正准备用MySQL和InnoDB测试相同的数据转储,但我已经无法将初始导入速度提高到InnoDB部分的可用速度.最初的倾倒花费了更长的时间,但这并没有让我担心:

$ for i in testdb_myisam testdb_innodb; do time mysqldump --extended-insert $i > $i.sql; done

real    0m38.152s
user    0m8.381s
sys     0m2.612s

real    1m16.665s
user    0m6.600s
sys     0m2.552s

然而,导入时间却大不相同:

$ for i in  testdb_myisam testdb_innodb; do time mysql $i < $i.sql; done

real    2m52.821s
user    0m10.505s
sys     0m1.252s

real    87m36.586s
user    0m10.637s
sys     0m1.208s

经过研究,我用了Changing tables from MyISAM to InnoDB make the system slow多个,然后用了set global innodb_flush_log_at_trx_commit=2个:

$ time mysql testdb_innodb < testdb_innodb.sql

real    64m8.348s
user    0m10.533s
sys     0m1.152s

伊姆霍仍然慢得惊人.我还为这些测试禁用了log_bin,下面是all mysql variables个列表.

我必须接受这样长的InnoDB时间,还是可以改进?我完全控制这个MySQL服务器,因为它完全是为了这个测试环境.

我只能在初始导入时应用特殊配置,并在应用程序测试时将其更改回,以便更好地匹配生产环境.

Update:

根据反馈,我禁用了自动提交和各种判断:

$ time ( echo "SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0;" \
; cat testdb_innodb.sql ; echo "COMMIT;" ) | mysql testdb_innodb;date

real    47m59.019s
user    0m10.665s
sys     0m2.896s

速度提高了,但没有那么多.我的测试有缺陷吗?

Update 2:

我能进入另一台机器,只花了大约8分钟.我比较了这些配置,并将以下设置应用于我的MySQL安装:

innodb_additional_mem_pool_size = 20971520
innodb_buffer_pool_size = 536870912
innodb_file_per_table
innodb_log_buffer_size = 8388608
join_buffer_size = 67104768
max_allowed_packet = 5241856
max_binlog_size = 1073741824
max_heap_table_size = 41943040
query_cache_limit = 10485760
query_cache_size = 157286400
read_buffer_size = 20967424
sort_buffer_size = 67108856
table_cache = 256
thread_cache_size = 128
thread_stack = 327680
tmp_table_size = 41943040

通过这些设置,我现在只需要大约25分钟.距离MyISAM所需的几分钟还有很长的路要走,但它对我来说越来越有用了.

推荐答案

你有没有试过InnoDB Performance Tuning Tips中的Bulk Data Loading Tips(尤其是第一个):

  • 将数据导入InnoDB时,确保MySQL没有

    SET autocommit=0;
    ... SQL import statements ...
    COMMIT;
    

    如果使用mysqldump选项--opt,则会得到

  • 如果在辅助键上有UNIQUE个约束,则可以加快表的速度

    SET unique_checks=0;
    ... SQL import statements ...
    SET unique_checks=1;
    

    对于大型表,这节省了大量磁盘I/O,因为InnoDB个磁盘可以使用

  • 如果表中有FOREIGN KEY个约束,则可以

    SET foreign_key_checks=0;
    ... SQL import statements ...
    SET foreign_key_checks=1;
    

    对于大型表,这可以节省大量磁盘I/O.

在我看来,整章都值得一读.

Mysql相关问答推荐

如何通过if语句对SQL查询进行排序

非常规字符的不正确字符串值错误

基于 2 列的重复行的 SQL 查询

如何使用 IF() 条件在 MySQL 中显示真假行

我将如何构建一个 SQL 查询来从交易表中选择第一次存款、第二次存款和额外存款

DECIMAL(m, n) 在 64 位系统中如何表示?

如何过滤表格,以便它显示最新的数据?

如何在 SQL 的计算列中显示小数点后两位?

如何在 SQL 中的一行中查找最小值和最大值?

无法在两个 mysql 表上执行内部联接

服务器返回无效的时区.转到高级选项卡并手动设置 servertimezone 属性

#1273 – 未知排序规则:‘utf8mb4_unicode_520_ci’

MySQL 5.7.12 导入无法从具有 CHARACTER SET 'binary' 的字符串创建 JSON 值

连接到 docker-compose mysql 容器会拒绝访问,但运行相同映像的 docker 不会

Laravel Eloquent 与查询构建器 - 为什么使用 eloquent 来降低性能

使用 mysql 处理非常大的数据

加入与子查询

服务器时区值“AEST”无法识别或代表多个时区

utf8mb4_unicode_ci 与 utf8mb4_bin

不使用 sudo 连接到 mysql 服务器