mysql - 如果您尝试更新正在查询的表,MySQL 会做什么?

标签 mysql performance

我有一个非常慢的查询,我需要不时地在 MySQL 数据库上运行。

我发现在查询完成之前,更新正在查询的表的尝试会被阻止。

我想这是有道理的,否则查询的结果可能会不一致,但这对我来说并不理想,因为查询的重要性远低于更新。

所以我的问题实际上有两个部分:

  1. 出于好奇,MySQL 在这种情况下究竟做了什么?它是否在查询期间锁定表?或者尝试在更新前锁定它?

  2. 有没有办法让慢查询不阻塞?我想选项可能是:

    • 在需要更新时终止查询。
    • 在更新发生之前对表的副本运行查询
    • 就让查询出错吧。

有人对此有任何想法吗?

最佳答案

听起来您正在使用 MyISAM 表,它使用表级锁定。在这种情况下,SELECT 将在表上设置一个共享锁。然后 UPDATE 将尝试请求独占锁并阻塞并等待 SELECT 完成。完成后,UPDATE 将正常运行。

MyISAM Locking

如果您切换到 InnoDB,那么默认情况下您的 SELECT 将不设置锁定。不需要像其他人建议的那样更改事务隔离级别(可重复读取是 InnoDB 的默认设置,并且不会为您的 SELECT 设置锁)。 UPDATE 将能够同时运行。 InnoDB 使用的多版本控制与 Oracle 处理这种情况的方式非常相似。 SELECT 唯一会设置锁的情况是,如果您在可序列化事务隔离级别中运行,您对查询有 FOR UPDATE/LOCK IN SHARE MODE 选项,或者它是某种写语句(例如 INSERT. ..SELECT) 并且您正在使用基于语句的二进制日志记录。

InnoDB Locking

关于mysql - 如果您尝试更新正在查询的表,MySQL 会做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/435209/

相关文章:

c# - 为什么使用 `Delegate.CreateDelegate` 创建的委托(delegate)比 lambda 和方法委托(delegate)更快?

javascript - v8/chrome/node.js函数内联

MYSQL:语法错误: 'DELETE' 在此位置输入无效

python - 为什么当使用 os.system() 或 subprocess.Popen() 从 Python 调用时我的 MySQL 存储过程不执行?

mysql - 数据库中 bool 值的约定

MySQL 重命名表,同时保留遗留代码的 View

php - 日期范围正好是 1 个月的 MySQL 查询

Mysql Group By 查询性能非常慢

java - 返回一个考虑日期和数字的值

c# - 给定数字列表中子系列的数量