【问题标题】:Mysql Insert into with select from myisam to innodbMysql Insert into with select from myisam to innodb
【发布时间】:2012-07-12 12:05:55
【问题描述】:

我有一个表,由多个工作应用程序访问,这些应用程序获取一批记录,对它们进行一些计算,然后将计算结果更新回该表中。该表目前是基于 MyISAM 的,但是由于我们对计算算法进行了一些更改,并且它导致了巨大的加速,我们看到了表上的大量锁,这是预期的,因为它是一个 MyISAM 表。 (该表中有大约 650-700 000 条记录)。

处理完所有记录后,会根据它生成报告并截断表格。一旦表被截断,一个进程会重新初始化它并重新开始循环。

我正在考虑将 MyISAM 表切换到 InnoDB 以防止锁定,但是使用 INSERT INTO .. SELECT .. FROM 语句(过去需要 3-4 分钟)初始化表的进程运行了 35-40 分钟当我决定停止它时。为什么是这样?有没有办法加快速度?

【问题讨论】:

  • 选择时 DESC 的输出是什么?
  • SELECT 中没有 WHERE 子句,所以它非常简单(这样做是有原因的,正如我所写的,当两个表都在 MyISAM 中时,插入需要 3-4 分钟. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------- -----------------+--------+----------------+------+-- -------+------+--------+-------+ | 1 | SIMPLE | table_name | ALL | NULL | NULL | NULL | NULL | 681233 | | +----+-------------+-------------------------+-- ----+---------------
  • 您可以尝试其他方法,例如导出/导入,但您的数据库很大,所以您需要耐心等待
  • 如果您的查询至少慢了 10 倍,我认为这不是耐心的问题... :(

标签: mysql insert innodb calculated-columns myisam


【解决方案1】:

MyISAM 按插入顺序存储记录。另一方面,InnoDB 的主键是聚集索引,因此记录的物理存储顺序与主键相同。因此,请确保您按主键顺序插入。您可以在 INSERT INTO ... SELECT 中添加 ORDER BY 子句。

此外,为避免拆分页面和重建二级索引,请在插入初始行后添加二级索引。所以,删除索引,然后重新添加它们。

此外,为避免行锁定(和自动增量锁定)开销,请使用 LOCK TABLES 显式锁定表。

最后,增加innodb_buffer_pool_size,否则你的索引建立起来会很慢。默认只有 8MB。

【讨论】:

  • 我正在做一个锁,对不起,我忘记了,所以它已经到位了。
  • 所以你的意思是 INSERT INTO .. SELECT .. FROM order by pk; ?很奇怪,我试试看。
  • @ZsoltJános,我添加到我的答案中。
  • 我用 order by(有 680 000 条记录)对我的系统进行了测试,没有任何区别,order by 稍微慢一些 - 虽然只用了 3 分 30 秒...
  • innodb_buffer_pool_size 将是解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多