我的查询非常慢,我需要不时在MySQL数据库上运行。
我发现在查询完成之前,会阻止尝试更新正在查询的表。
我想这是有道理的,否则查询的结果可能会不一致,但对我来说并不理想,因为查询的重要性远低于更新。
所以我的问题实际上有两个部分:
出于好奇,MySQL在这种情况下究竟做了什么?它是否在查询期间锁定表格?或者在更新之前尝试锁定它?
有没有办法让慢查询不阻塞?我猜选项可能是:
有人对此有任何想法吗?
答案 0 :(得分:5)
听起来您正在使用MyISAM表,它使用表级锁定。在这种情况下,SELECT将在表上设置共享锁。然后UPDATE将尝试请求独占锁定和阻塞,并等待SELECT完成。一旦完成,UPDATE将正常运行。
如果您切换到InnoDB,那么您的SELECT默认情况下不会设置锁定。没有必要像其他人推荐的那样更改事务隔离级别(InnoDB默认可重复读取,并且不会为SELECT设置锁定)。 UPDATE将能够同时运行。 InnoDB使用的多版本与Oracle处理这种情况的方式非常相似。 SELECTs设置锁定的唯一时间是,如果您在可序列化的事务隔离级别中运行,则查询具有FOR UPDATE / LOCK IN SHARE MODE选项,或者它是某种写入语句的一部分(例如INSERT。 ..SELECT)并且您正在使用基于语句的二进制日志记录。
答案 1 :(得分:1)
出于select语句的目的,您应该发出:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
连接上的命令,导致后续的select语句无锁定地运行
不要使用'SELECT ... FOR UPDATE
',因为它肯定会锁定受select语句影响的表行
msql事务isloation级别的完整列表是in the docs。
答案 2 :(得分:1)
首先,你需要知道你正在使用什么引擎(MySam或InnoDb)。
这显然是一个交易问题。
看看 13.4.6部分。 mysql手册中的SET TRANSACTION语法。
答案 3 :(得分:0)
我不知道MySQL,但这听起来像是交易问题。 您应该能够在选择查询中将事务类型设置为Dirty Read。
这不会给你正确的结果。但它不应该被阻止。
最好是让第一个查询更快。做一些分析并检查是否可以通过正确的独立来加速它等等。
答案 4 :(得分:0)
UPDATE LOW_PRIORITY ....可能会有所帮助 - mysql文档不清楚这是否会让请求更新的用户继续,并且更新发生在可能的时候(我认为这是发生的事情)或用户是否有等待(这会比现在更糟糕......),我不记得了。
您使用的是哪种表类型?如果您使用的是MyISAM,切换到InnoDB(如果可以的话 - 它没有全文索引)会为这类事情开辟更多选项,因为它支持事务功能和行级锁定。