mysql - 为什么我在写入 300KB/sec 时绑定(bind)了 I/O 以写入 MySQL?

标签 mysql sql database optimization scalability

<分区>

我正在向具有 MySQL 专业知识的人寻求帮助。我不需要一个确切的解决方案 - 只是一些想法和寻找优化的地方。

关于问题的一点点:

  • 我需要将大量行插入到 InnoDB 表中。
  • 每个表只有一个索引(也是主键)
  • 每行大约有 1KB 的数据。
  • 我正在使用一次约 5000 行的加载数据 INFILE 查询。
  • 我使用 8 个线程进行写入(每个写入单独的数据)。

好的,有了这些特性,我的数据库写入吞吐量约为每小时 100 万行。这大约是 1 GB 的数据或 ~300KB/秒,基于一行中数据量的上限。

但是,当我查看我的机器统计信息时,我注意到磁盘的 I/O 图以大约 20 MB/秒的速度写入平坦线,这表明我受 I/O 限制。 (CPU 图也达到 100%,但其中约 90% 是 iowait)。所以,我的问题是,当通过查询发送的数据量约为 5 KB/秒时,为什么 MySQL 会以大约 20 MB/秒的速度将数据写入磁盘。

我猜测差异是由日志文件、临时表和事务加倍引起的 - 但我想知道为什么这个比率接近 100:1?以及如何将这个比例缩小到更合理的水平?什么样的内部变量导致 MYSQL 将如此多的数据写出到磁盘而不是将其存储在内存中?例如,我已经设置了 innodb_buffer_pool_size = 12G、max_heap_table_size = 8G 和 tmp_table_size = 6G,试图让 MySQL 使用更多内存而不是磁盘 - 但结果仍然相同。

非常感谢您能给我的任何帮助和建议!

最佳答案

八个写入线程可能太高或太低,具体取决于您的存储实际情况。

如果您的计算机中有一个旋转的金属驱动器,这太高了——您的驱动器将到处寻找以执行写入。使用一个线程。

如果您将数据库表分散在八个或更多 SSD 驱动器上,这可能没问题,但也许更多的线程可以让您充分利用极低的“查找”延迟。 (“Seek”并不真正适用于较新的 SSD 设备,但我通过类比较旧的驱动器技术来使用该术语。)

关于mysql - 为什么我在写入 300KB/sec 时绑定(bind)了 I/O 以写入 MySQL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8394340/

相关文章:

PHP MySQL 数据库备份

C# 和 PostgreSQL

MySQL 将数据从一个表移动到另一个表,匹配 ID

sql-server - 在不同的设置上使 SQL Server 中的 Microsoft Access 表相同

php - mysqli_fetch_field() 多次输出字段名称

python - 在 MySQL 中存储非常大的整数

mysql - 在 Ruby 1.8.7 中插入 MySQL 数据库时,Unicode 格式丢失

php - 如果 LEFT OUTER JOIN 找到行,则创建子 <li> 项

c# - 使用 LINQ 插入数据库

mysql - 如何仅返回查询中的特定列