假设B树索引,表的大小会减慢日志N的索引插入速度。
这是否意味着插入每个新行时,插入速度将减慢因子log N,其中N,我假设是行数?即使我只在一个查询中插入所有行?即:
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秒。如何优化这一点,因为每天都要添加新数据,插入时间将继续减慢。
此外,除了可能有帮助的查询之外还有什么吗?也许一些配置设置?
我读到在插入之前删除索引可能有助于插入速度。插入后,我再次添加索引。但是这里唯一的索引是主键,在我看来放弃它对我来说没什么用。此外,虽然主键是已删除,但所有选择查询都会变慢。
我不知道任何其他可能的方法。
编辑:以下是一些关于在表格中插入~60,000行的测试,其中包含~1.47 mil行:
使用上述简单查询: 146秒
使用MySQL的LOAD DATA infile: 145秒
使用MySQL的LOAD DATA infile并按照David Jashi的回答拆分csv文件: 136个文件,60个文件,每个1000行,6个文件136秒,每个10,000行
删除并重新添加主键:键删除需要11秒,插入数据需要0.8秒,重新添加主键需要153秒,完全需要~165秒
答案 0 :(得分:18)
如果您想要快速插入,首先需要的是适当的硬件。这假设有足够的RAM,SSD而不是机械驱动器和相当强大的CPU。
由于你使用InnoDB,你想要的是优化它,因为默认配置是为慢速和旧机器设计的。
Here's a great read about configuring InnoDB
之后,您需要了解一件事 - 这就是数据库在内部执行操作的方式,硬盘驱动器的工作方式等等。我将在以下描述中简化机制:
一个事务是MySQL等待硬盘确认它写入了数据。这就是机械驱动器上交易速度慢的原因,它们每秒可以进行200-400次输入输出操作。翻译,这意味着您可以在机械驱动器上使用InnoDB每秒获得200次插入查询。当然,这是简化的解释,只是为了概述正在发生的事情,它不是交易背后的完整机制。
由于查询(尤其是与表大小相对应的查询)在字节方面相对较小 - 因此您实际上会在单个查询上浪费宝贵的IOPS。
如果你在一个事务中包装多个查询(100或200或更多,没有确切的数字,你必须测试),然后提交它 - 你将立即实现每秒更多的写入。
Percona家伙在相对便宜的硬件上实现了15k插入一秒钟。即使是5k插入一秒也不错。像你这样的表很小,我在类似的表上做了测试(3列以上),我设法得到10亿条记录没有明显的问题,使用16GB RAM机器和240GB SSD(1个驱动器,没有RAID,用于测试目的)。
TL; DR: - 按照上面的链接,配置您的服务器,获取SSD,在1个事务中包含多个插入并获利。并且不要关闭索引然后打开它,它总是不适用,因为在某些时候你将花费处理和IO时间来构建它们。
答案 1 :(得分:4)
无论如何,删除索引肯定会有所帮助。另请考虑使用LOAD DATA
。您可以找到一些比较和基准here
此外,在构造PRIMARY KEY时,请按顺序使用表中第一个字段,即在结构中切换第二个和第三个字段的位置。
答案 2 :(得分:3)
如果您正在进行一百万行的批量插入,那么删除索引,执行插入以及重建索引可能会更快。但是,如果您的问题是单行插入花费的时间太长,那么您还有其他问题(例如内存不足),并且删除索引也无济于事。
答案 3 :(得分:1)
建立/重建索引是您要加速的目标。如果您必须具有此表/密钥结构,更快的硬件和/或调整服务器配置以加快索引构建可能是答案 - 确保您的服务器和设置可以在内存中完成。
否则,考虑使用可提高插入速度的结构进行权衡。或者,想想你可以快乐地生活3分钟插入的方式。
答案 4 :(得分:0)
在某些情况下,我发现以中等大小的块插入事务会有所帮助,因为有时似乎允许进行一些批量操作。在其他情况下,这可能是由于锁定和事务开销而使事情变慢了。