16

MySQL Docs说:

假设 B-tree 索引,表的大小会减慢 log N 的索引插入速度。

这是否意味着对于每个新行的插入,插入速度将减慢 log N 的因子,其中 N,我假设是行数?即使我在一个查询中插入所有行?IE :

INSERT INTO mytable VALUES (1,1,1), (2,2,2),  (3,3,3), .... ,(n,n,n)

其中 n 约为 70,000

我目前在具有以下结构的表中有约 147 万行:

CREATE TABLE mytable (
   `id` INT,
   `value` MEDIUMINT(5),
   `date` DATE,
   PRIMARY_KEY(`id`,`date`)
) ENGINE = InnoDB

当我以上述方式插入事务时,提交时间约为 275 秒。我该如何优化这一点,因为每天都会添加新数据,并且插入时间会继续减慢。

此外,除了可能有帮助的查询之外,还有什么其他的吗?也许一些配置设置?

可能的方法 1 - 删除索引

我读到在插入之前删除索引可能有助于插入速度。插入后,我再次添加索引。但是这里唯一的索引是主键,我认为删除它并没有多大帮助。此外,当主键被删除时,所有的选择查询都会变得非常缓慢。

我不知道任何其他可能的方法。

编辑:以下是在表中插入约 60,000 行的一些测试,其中约 147 万行:

使用上述普通查询: 146 秒

使用 MySQL 的 LOAD DATA infile: 145 秒

使用 MySQL 的 LOAD DATA infile 并按照 David Jashi 在他的回答中的建议拆分 csv 文件: 136 秒用于 60 个文件,每个文件 1000 行,136 秒用于 6 个文件,每个文件 10,000 行

删除和重新添加主键:删除密钥需要 11 秒,插入数据需要 0.8 秒,但重新添加主键需要 153 秒,总共需要约 165 秒

4

5 回答 5

24

如果您想要快速插入,首先需要的是合适的硬件。这假设有足够数量的 RAM、SSD 而不是机械驱动器和相当强大的 CPU。

由于您使用 InnoDB,因此您想要优化它,因为默认配置是为慢速和旧机器设计的。

这是有关配置 InnoDB 的精彩读物

在那之后,你需要知道一件事——那就是数据库如何在内部完成它们的工作,硬盘是如何工作的等等。我将在下面的描述中简化机制:

事务是 MySQL 等待硬盘驱动器确认它写入数据。这就是机械驱动器上的事务处理速度慢的原因,它们每秒可以进行 200-400 次输入输出操作。翻译过来,这意味着您可以在机械驱动器上使用 InnoDB 每秒获得​​ 200 次插入查询。当然,这是简化的解释,只是为了概述正在发生的事情,它不是 transaction 背后的完整机制

由于查询,尤其是与表大小相对应的查询,在字节方面相对较小 - 您实际上在单个查询上浪费了宝贵的 IOPS。

如果您在单个事务中包装多个查询(100 或 200 或更多,没有确切的数字,您必须测试)然后提交它 - 您将立即实现每秒更多的写入。

Percona 的家伙在相对便宜的硬件上实现了每秒 15k 的插入。即使每秒插入 5k 也不错。像你这样的表很小,我已经在一个类似的表(3 列以上)上进行了测试,我使用 16GB 内存机器和 240GB SSD(1 个驱动器,没有 RAID,用于测试目的)。

TL;DR: - 按照上面的链接,配置您的服务器,获得 SSD,在 1 个事务中包装多个插入并获利。并且不要关闭索引然后再打开,它并不总是适用,因为在某些时候您将花费处理和 IO 时间来构建它们。

于 2013-06-07T15:43:19.543 回答
6

无论如何,删除索引肯定会有所帮助。也考虑使用LOAD DATA. 你可以在这里找到一些比较和基准

此外,在构造 PRIMARY KEY 时,请按顺序使用表中首先出现的字段,即交换结构中第二个和第三个字段的位置。

于 2013-06-07T06:52:48.600 回答
3

如果您正在执行一百万行的批量插入,那么删除索引、执行插入和重建索引可能会更快。但是,如果您的问题是单行插入花费的时间太长,那么您还有其他问题(例如内存不足)并且删除索引将无济于事。

于 2013-06-07T06:59:35.040 回答
1

构建/重建索引是您要加快速度的方法。如果您必须拥有此表/键结构,更快的硬件和/或调整服务器配置以加快索引构建可能是答案 - 确保您的服务器和设置可以在内存中完成。

否则,请考虑权衡可提高插入速度的结构。或者,想想你可以用 3 分钟的插曲愉快地生活的方式。

于 2013-06-07T15:06:08.043 回答
0

我发现在某些情况下以中等块插入事务会有所帮助,因为它有时似乎允许一些批量操作。在其他情况下,大概是由于锁和事务的开销,它使事情变慢了。

于 2020-02-28T02:32:15.840 回答