一. 使用批量插入,将多条单独的 insert 合并成一次操作

即:insert into table values (a1, b1, c1), (a2, b2, c2);

解析:将多条 insert 合并后,减少MySQL日志量(即MySQL的 binlog 和 innodb 的事务日志),降低日志刷盘的数据量和频率,从而提高效率。通过合并多条 insert 语句,还能减少SQL语句的解析次数,减少和数据库的交互,减少了网络传输的IO。

二. 修改批量插入缓冲区大小参数: bulk_insert_buffer_size,调大批量插入的缓存

这个参数默认为 8M,例如设置成 100M

set global bulk_insert_buffer_size = 1024*1024*100;

三. 设置 innodb_flush_log_at_trx_commit = 0

相对于 innodb_flush_log_at_trx_commit = 1, 设置为 0 可以明显的提高导入的速度。

set global innodb_flush_log_at_trx_commit=0;

解析:

0: log buffer 中的数据将以每秒一次的频率写入到 log file 中,且同时会进行文件系统到磁盘的同步操作,但是每个事务的 commit 并不会触发任何的 log buffer 到 log file 的刷新或者从文件系统到磁盘的刷新操作。

1: 在每次事务提交的时候将 log buffer 中的数据都会写入到 log file,同时也会触发文件系统到磁盘的同步;

2: 事务提交会触发 log buffer 到 log file 的刷新,但并不会触发磁盘文件系统到磁盘的同步。此外,每秒会有一次文件系统到磁盘的同步操作。

四. 设置事务提交为 手动提交

因为 MySQL 事务默认是自动提交的(autocommit),这样每插入一条数据,都会进行一次 commit,所以通过手动提交事务,可以减少创建事务时的消耗。一般可以设置为 1000 条insert 提交一次。
【解决方案1】:

通过在 my.cnf中添加以下行。我能够做到。

innodb_autoinc_lock_mode =2sync_binlog=1bulk_insert_buffer_size=512Mkey_buffer_size=512Mread_buffer = 50MMax_allowed_packet=1MNet_buffer_length=8k

innodb_flush_log_at_trx_commit=2,我在另一个链接中看到它说它将速度提高到 160 倍。 输出性能:超过 24 小时到 2 小时;

通常将innodb_buffer_pool_size其配置为物理内存的50%到75%

innodb_flush_log_at_trx_commit,1改为了0

2.尝试修改参数加快导入速度

在MySQL中,有一对大名鼎鼎的“双一”参数,即 innodb_flush_log_at_trx_commit 与 sync_binlog 。为了安全性这两个参数默认值为1,为了快速导入脚本,我们可以临时修改下这两个参数,下面简单介绍下这两个参数:

innodb_flush_log_at_trx_commit默认值为1,可设置为0、1、2

如果innodb_flush_log_at_trx_commit设置为0,log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。 如果innodb_flush_log_at_trx_commit设置为1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去. 如果innodb_flush_log_at_trx_commit设置为2,每次事务提交时MySQL都会把log buffer的数据写入log file.但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。

sync_binlog默认值为1,可设置为[0,N)

当sync_binlog =0,像操作系统刷其他文件的机制一样,MySQL不会同步到磁盘中去而是依赖操作系统来刷新binary log。 当sync_binlog =N (N>0) ,MySQL 在每写 N次 二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中去。

这两个参数可以在线修改,若想快速导入,可以按照下面步骤来操作:

#1.进入MySQL命令行临时修改这两个参数setglobalinnodb_flush_log_at_trx_commit=2;setglobalsync_binlog=2000;#2.执行SQL脚本导入mysql-uroot-pxxxxxxtestdb<testdb.sql#3.导入完成再把参数改回来setglobalinnodb_flush_log_at_trx_commit=1;setglobalsync_binlog=1;

还有另外一种场景是你的需求是新建从库,或者是不需要产生binlog,这时候导入SQL脚本时可以设置暂时不记录binlog,可以在脚本开头增加 set sql_log_bin=0; 然后再执行导入,这样速度会进一步加快。如果你的MySQL实例没有开启binlog则不需要再执行该语句了。

max_connection=1000

innodb_file_per_table=1

innodb_buffer_pool_size=1G

innodb_log_file_size=256M

innodb_log_buffer_size=256M

innodb_flush_log_at_trx_commit=2 需要放mysqlld_safe节点下。

symbolic-links=0
innodb_lru_scan_depth=256
#sync_binlog=0
#innodb_flush_log_at_trx_commit=0
wait_timeout=2880000
#interactive_time=2880000
max_allowed_packet=1G
max_connections = 1000
innodb_file_per_table=1
innodb_buffer_pool_size=10G
innodb_log_file_size=256M
innodb_log_buffer_size=256M
bulk_insert_buffer_size = 1G
innodb_flush_log_at_trx_commit=0
innodb_autoinc_lock_mode =2
sync_binlog=0
bulk_insert_buffer_size=512M
key_buffer_size=512M
#read_buffer=50M
net_buffer_length=8k
character_set_server = utf8mb4
sql_mode = NO_ENGINE_SUBSTITUTION

MySQL大数据量插入数据参数优化

关于一些配置项优化
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock

[mysql.server]
pid-file = /var/lib/mysql/localhost.pid

[mysqld]
port = 3306
socket =/var/lib/mysql/mysql.sock

# 网络传输中一次消息传输量的最大值。系统默认值 为1MB,最大值是1GB,必须设置1024的倍数。
# 因为后续我们在代码中是使用prepareStatement.addBatch(),单次传输的值会比较大,所以这个参数必须加大。
max_allowed_packet = 32M
# 缓冲池大小,只需要用Innodb的话则可以设置它高达 70-80% 的可用内存。
innodb_buffer_pool_size = 5120M
innodb_buffer_pool_instances=3
innodb_additional_mem_pool_size = 1024M
innodb_log_files_in_group = 3
innodb_lock_wait_timeout = 120
# 刷新日志频率
open_files_limit = 10240
back_log = 600
innodb_log_file_size=110M
# 连接数
max_connections = 3000
max_connect_errors = 6000
# 多线程
thread_cache_size = 300
thread_concurrency = 16
thread_stack = 192KB
innodb_write_io_threads = 32
innodb_purge_threads=1
# 刷新脏页频率
innodb_max_dirty_pages_pct=90
wait_timeout=300

详细的参数配置
innodb缓冲池相关配置

MySQL性能优化