我有一个非常慢的查询,我需要不时地在 MySQL 数据库上运行。
我发现在查询完成之前,更新正在查询的表的尝试会被阻止。
我想这是有道理的,否则查询的结果可能会不一致,但这对我来说并不理想,因为查询的重要性远低于更新。
所以我的问题实际上有两个部分:
出于好奇,MySQL 在这种情况下究竟做了什么?它是否在查询期间锁定表?或者尝试在更新前锁定它?
有没有办法让慢查询不阻塞?我想选项可能是:
- 在需要更新时终止查询。
- 在更新发生之前对表的副本运行查询
- 就让查询出错吧。
有人对此有任何想法吗?
最佳答案
听起来您正在使用 MyISAM 表,它使用表级锁定。在这种情况下,SELECT 将在表上设置一个共享锁。然后 UPDATE 将尝试请求独占锁并阻塞并等待 SELECT 完成。完成后,UPDATE 将正常运行。
如果您切换到 InnoDB,那么默认情况下您的 SELECT 将不设置锁定。不需要像其他人建议的那样更改事务隔离级别(可重复读取是 InnoDB 的默认设置,并且不会为您的 SELECT 设置锁)。 UPDATE 将能够同时运行。 InnoDB 使用的多版本控制与 Oracle 处理这种情况的方式非常相似。 SELECT 唯一会设置锁的情况是,如果您在可序列化事务隔离级别中运行,您对查询有 FOR UPDATE/LOCK IN SHARE MODE 选项,或者它是某种写语句(例如 INSERT. ..SELECT) 并且您正在使用基于语句的二进制日志记录。
关于mysql - 如果您尝试更新正在查询的表,MySQL 会做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/435209/