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

Preventing lock wait timeouts with INSERT ... SELECT

我的应用程序有一个 InnoDB books table。每天几次,大量独立 INSERTUPDATE 查询 运行 针对 books table.

应用程序的传入请求也会根据 books 使用 INSERT INTO [tmp table] (SELECT FROM books ...).

生成临时 table

根据 the MySQL docs on INSERT ... SELECT,此语法锁定 books,直到填充临时 table。

selectbookstable 上的这些 select 锁、插入和更新的组合周期性地淹没 MySQL,导致锁等待超时。

我已经尝试了 this percona article 的建议,将 books 中的 SELECT 转储到一个输出文件中,将 INSERT 作为一个单独的步骤执行。这避免了 select 锁,但加载速度非常慢。

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

我是一个 MySQL 菜鸟,可能对问题的理解有误,但是

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

不应该对 books table 设置任何锁,而只能对 tmp_table 设置任何锁,除非你的事务隔离级别是 SERIALIZABLE。

UPDATEs 可以是 运行 在 READ COMMITTED 隔离级别上,这样 InnoDB 就不需要在每一行上持有锁直到事务结束(尽管这仅在 WHERE 部分仅包含索引列时有效).