2

我正在研究提高 mysql 插入性能的方法。

关于场景,在忙碌的一天,大表每 3 秒大约 3000 行,中表另外 100 行,小表并发大约 30 行。这必须持续 24 小时,然后我选择只有 30.000-40.000 行的重要部分,然后我将刷新所有 3 个表。

所以,我使用的是 mysql 5.5.29。所有表都使用innodb,索引和主键很少。

关于这个问题,我看到了一条关于为这些插入使用内存引擎表然后将它们移动到主表的评论:

“使用 LOCK TABLE .. WRITE 可能会加快插入速度,但在处理和加载行时,您将锁定任何阅读器。主键上的选择(应该接近 0 秒)在我的情况下最多需要 0.2 秒loader 正忙于加载 1000 行的批次。

一个很好的解决方法是将新行放入临时表中,然后不时地在单个事务中刷新该表。这使得插入非常快,因为所有的检查和转换都已经在临时表中完成了。

CREATE TEMPORARY TABLE ..._temp (....) ENGINE=MEMORY;

-- Loop from here --
DELETE FROM .._temp;
INSERT INTO .._temp ... VALUES (...);
INSERT INTO .._temp ... VALUES (...);

LOCK TABLE ... WRITE, ..._temp READ;
INSERT INTO ... SELECT * FROM ..._temp;
UNLOCK TABLES;
-- Repeat until done --

DROP TABLE ..._temp;

我在我的系统中看到,INSERT 的运行速度与锁定表时的速度大致相同,但客户端在加载程序运行时根本没有注意到任何性能损失。”

来源

在这种情况下使用内存引擎有意义吗?如果需要访问行,我应该使用 innodb 来避免表锁,还是应该使用 myisam 来提高速度?

4

1 回答 1

4

如果您需要每天擦桌子,但需要先从中取出数据。最好的办法是用一个新的空表快速替换现有的完整表,然后在整个表上执行您需要的任何数据操作。这是你如何做到的。

首先创建一个表,就像您要操作的表一样:

CREATE TABLE big_table_temp LIKE big_table;

您现在有一个与大表具有相同架构的空表。

然后重命名表以交换它们:

RENAME TABLE big_table TO big_table_archive, big_table_temp TO big_table;

这样做的好处是这个操作基本上是瞬时的,因为 MySQL 只是重命名磁盘上的二进制数据库文件。确保您在一个这样的查询中同时进行了重命名操作,因为您希望操作作为一个整体成功或失败。

然后,您可以big_table_archive根据需要进行操作,从中提取数据,而不必担心会阻塞big_table.

于 2013-03-02T01:13:44.473 回答