我有一个带有2个字段f1和f2的MyISAM表,这两个字段都是无符号整数,不能为空。该表故意没有主键,但它有一个f2的索引。该表目前有3.2亿行。
我希望能够以合适的速度将新行(每周约4000次)插入此表中。但是,目前我在2分钟内插入了大约4000行。 (我使用文本文件和“source”命令执行此操作 - 文本文件仅包含此表中的INSERT语句)。有没有办法可以加快插入语句的速度?此外,在执行INSERT语句时,同一个表中的任何SELECT / JOIN语句是否会受到影响或减慢?
答案 0 :(得分:3)
您可以从
中批量插入语句INSERT INTO table (f1, f2) VALUES ($f1, $f2);
INSERT INTO table (f1, f2) VALUES ($other, $other);
etc...
进入
INSERT INTO table (f1, f2) VALUES ($f1, $f2), ($other, $other), etc...
这会减少解析开销。这可能会加快速度。但是,请不要过分对插入进行分组,因为查询受max_allowed_packet
设置的约束。
2分钟内4000行仍然是每秒33行。这不是太破旧,特别是在一个必须更新索引的巨大表上。您可以在执行插入之前禁用表上的键,然后使用REPAIR TABLE
再次重新生成密钥,但这可能需要更长时间,尤其是要扫描3.2亿行。你必须做一些基准测试才能看出它是否值得。
对于SELECTS / JOINS,由于你在MYISAM表上,所以在完成所有操作之前,无法在事务中隐藏新表。除非您锁定表以便对插入进行独占访问,否则每行都会在输入时立即对其他会话可见。但是,当插件运行时,你已经锁定了其他所有人。
答案 1 :(得分:0)
据我所知,source
- 命令是执行此操作的最快方法。由于该表是MyISAM,因此在写入操作期间会锁定整个表。所以是的,所有SELECT
- 语句都排队,直到所有插入/更新/删除完成。
答案 2 :(得分:0)
答案 3 :(得分:0)
@rjk是对的。 LOAD DATA INFILE是将数据输入表格的最快方式。很少有其他的想法。
对于我来说,4分钟对我来说似乎很长一段时间。 SELECT会阻止MyISAM中的INSERT,并可能减慢插入速度。我强烈建议InnoDB没有这个问题加上更好的崩溃恢复等。如果你必须使用MyISAM,在运行你的插入之前锁定表可能有帮助,或者你可以尝试INSERT DELAYED,这将允许INSERT语句立即返回并且是当桌子空闲时处理。