2009-01-12 20 views
2

我有一个非常慢的查询,我需要不时在MySQL数据库上运行。如果您尝试更新正在查询的表,MySQL会执行什么操作?

我发现尝试更新正在查询的表将被阻止,直到查询完成。

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

所以我的问题真的有两个部分:

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

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

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

任何人有什么想法?

回答

5

这听起来像你正在使用MyISAM表,它使用表级锁定。在这种情况下,SELECT将在表上设置一个共享锁。然后,UPDATE将尝试请求排它锁和块,并等待SELECT完成。一旦完成,UPDATE将像正常一样运行。

MyISAM Locking

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

InnoDB Locking

0

我不知道MySQL,但它听起来像事务问题。 您应该能够在您的选择查询中将事务类型设置为脏读。

这并不总是给你正确的结果。但它不应该被阻止。

更好的办法是让第一个查询更快。做一些分析,并检查是否可以通过正确的缩进等来加速它。

0

UPDATE LOW_PRIORITY ....可能会有所帮助 - mysql文档不清楚这是否会让用户请求更新继续,更新是在可能时发生(这是我认为会发生的情况)还是用户必须等待(这会比现在更糟糕......),我不记得了。

您使用的是哪种表格类型?如果你在MyISAM上,切换到InnoDB(如果可以的话 - 它没有全文索引)为这类事情开辟了更多的选择,因为它支持事务特性和行级锁定。

+0

谢谢。不幸的是,我被困在MyISAM中......否则,听起来像切换到InnoDB将是答案... – Ben 2009-01-12 15:23:48

+0

UPDATE LOW_PRIORITY不允许UPDATE与SELECT相同。它在决定下一次要授予的锁定时与排队顺序有关。 – 2009-01-12 15:57:00

1

SELECT语句的目的,你应该发出:连接,这将导致随后的SELECT语句无锁定操作上
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
命令。
请勿使用'SELECT ... FOR UPDATE',因为这肯定会锁定受select语句影响的表行。
msql事务分区级别的完整列表是in the docs

1

首先你需要知道你使用的是什么引擎(MySam或InnoDb)。

这显然是一个交易问题。

看一看13.4.6。 SET TRANSACTION语法在mysql手册中。

相关问题