大量插入的 InnoDB 表不会使用我所有的 CPU

sep*_*332 8 mysql innodb myisam optimization mysql-5.5

我有一个几乎从不查询的数据包日志数据库。它只需要快速插入即可。我使用 InnoDB 是因为我想保持 ACID 合规性,因为即使丢失一个数据包也可能对我们的客户造成损害。在性能调优方案中,我通过多个数据库连接向服务器发送 1,000,000 个数据包。但是无论我在 my.cnf 中使用什么设置,我都无法让 mysqld 进程在 12 核的系统上使用超过 900% 的 CPU。(盒子上没有其他东西在运行。)

我设置了以下内容

  • innodb_file_per_table = 1
  • innodb_write_io_threads = 64
  • innodb_read_io_threads = 64
  • innodb_thread_concurrency = 0

如果我使用 MyISAM,我可以在大约 6 秒内写入所有数据包。但是 InnoDB 大约需要 25。我可以让 MySQL 使用剩余的系统资源并更快地插入吗?

编辑:这是表的架构:

+-------+----------------------+------+-----+---------+-------+
| Field | Type                 | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| t     | bigint(20) unsigned  | YES  |     | NULL    |       |
| a     | char(1)              | YES  |     | NULL    |       |
| sa    | int(10) unsigned     | YES  |     | NULL    |       |
| sb    | int(10) unsigned     | YES  |     | NULL    |       |
| sc    | int(10) unsigned     | YES  |     | NULL    |       |
| sd    | int(10) unsigned     | YES  |     | NULL    |       |
| sp    | smallint(5) unsigned | YES  |     | NULL    |       |
| da    | int(10) unsigned     | YES  |     | NULL    |       |
| db    | int(10) unsigned     | YES  |     | NULL    |       |
| dc    | int(10) unsigned     | YES  |     | NULL    |       |
| dd    | int(10) unsigned     | YES  |     | NULL    |       |
| dp    | smallint(5) unsigned | YES  |     | NULL    |       |
+-------+----------------------+------+-----+---------+-------+
Run Code Online (Sandbox Code Playgroud)

编辑 2:我将更多的插入一起批处理,以便单个查询接近最大长度(大约 16,000,000 个字符)。数据库现在在两秒钟内飙升至 1100%,然后在其余时间下降至 100%。总时间现在是 21 秒,比我开始时快了大约 16%。

Rol*_*DBA 7

您还必须启动innodb_io_capacity

默认值为 200。对于初学者,将其提高到 5000。我会去20000。

您可能还希望确保ib_logfile0ib_logfile1足够大。innodb_log_file_size的默认值为5M。对于初学者,我会将其提高到 1G。

更大的 InnoDB 缓冲池也会有所帮助,也许是 4G。

回顾一下,请使用以下附加设置:

[mysqld]
innodb_io_capacity=5000
innodb_buffer_pool_size=4G
innodb_log_file_size=1G
Run Code Online (Sandbox Code Playgroud)

将这些设置添加到 my.cnf 后,要调整 ib_logfile0/ib_logfile1 的大小,请执行以下操作

service mysql stop
rm -f /var/log/mysql/ib_logfile[01]
service mysql start
Run Code Online (Sandbox Code Playgroud)

重新创建文件 ib_logfile0 和 ib_logfile1。别担心,我已经做过很多次了

您可能需要为 InnoDB 做一些与众不同的事情

请尝试以下操作:

  • InnoDB 表上的全表锁定
  • 执行批量加载
  • 解除锁定