使用INSERT ... SELECT防止锁定等待超时

时间:2019-01-25 22:05:11

标签: mysql mariadb innodb

我的应用程序有一个InnoDB books表。每天有几次针对INSERT表运行大量独立的UPDATEbooks查询。

对应用程序的传入请求还使用books基于INSERT INTO [tmp table] (SELECT FROM books ...)生成了一个临时表。

根据the MySQL docs on INSERT ... SELECT,此语法将锁定books,直到已填充临时表为止。

books表上这些选择,插入和更新的锁组合会定期使MySQL崩溃,从而导致锁等待超时。

我尝试了以下建议:this percona articleSELECT中的books转储到外文件中,并单独执行INSERT。这样可以避免选择锁定,但是加载速度过慢。

我是否缺少INSERT ... SELECT的替代方案,该替代方案不会在不牺牲性能的情况下锁定books表?

1 个答案:

答案 0 :(得分:1)

我是MySQL菜鸟,可能对问题的理解不正确,但是

INSERT INTO [tmp table] (SELECT FROM books ...)

除非您的事务隔离级别为SERIALIZABLE,否则不应为books表设置任何锁,而只能为tmp_table设置锁。

更新可以在READ COMMITTED隔离级别上运行,因此InnoDB不需要在事务结束前的每一行上都保持锁(尽管仅在WHERE部分仅由索引列组成的情况下才有效)。