任何方式选择而不会导致MySQL锁定?

omg*_*omg 119 mysql locking

查询:

SELECT COUNT(online.account_id) cnt from online;
Run Code Online (Sandbox Code Playgroud)

但是在线表也被事件修改,因此我经常可以通过运行看到锁定show processlist.

MySQL中是否有任何语法可以使select语句不引起锁定?

而且我忘了在上面提到它是在MySQL奴隶数据库上.

我加入my.cnf:transaction-isolation = READ-UNCOMMITTED 奴隶后会遇到错误:

错误'无法进行二进制日志记录.消息:InnoDB中的事务级别"READ-UNCOMMITTED"对于查询的binlog模式"STATEMENT"不安全

那么,是否有兼容的方法来做到这一点?

Jon*_*son 157

找到一篇名为"MYSQL WITH NOLOCK"的文章

https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx

在MS SQL Server中,您将执行以下操作:

SELECT * FROM TABLE_NAME WITH (nolock)
Run Code Online (Sandbox Code Playgroud)

和MYSQL等价

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
Run Code Online (Sandbox Code Playgroud)

编辑

Michael Mior建议如下(来自评论)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;
Run Code Online (Sandbox Code Playgroud)

  • 只是给未来读者一个注意事项,您可能希望消除"SESSION",从而使交易级别仅适用于下一个交易.然后,只需用`COMMIT`替换上面的第三个语句.在这种情况下,这将是一个noop,但具有结束事务和重置为默认隔离级别的副作用. (48认同)
  • 谢谢,所以这对Innodb有用,但如果MyISAM怎么办? (6认同)
  • 对不起,但是我不得不在这里回答这个问题,因为这里没有提到InnoDB和MyISAM之间非常重要的区别.如上面的@omg所述,这适用于InnoDB,但不适用于MyISAM表. (5认同)
  • 只是一个注释,该链接已死...... :( (3认同)
  • @Craig MyISAM没有在SELECT查询期间不发出READ锁是不正确的-有*锁,与InnoDB相对的是表锁,阻塞了所有请求的WRITE锁*和*执行期间的所有后续查询。最初的问题似乎与InnoDB有关,而且MyISAM也不存在隔离级别-[SET TRANSACTION`语句的文档](http://dev.mysql.com/doc/refman/5.0/en/ set-transaction.html)状态:*“此语句设置事务隔离级别,用于对InnoDB表进行操作。” * (2认同)

Ale*_*lli 23

如果表是InnoDB,请参阅http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html - 它对SELECT使用一致读取(无锁定模式)"如果设置了innodb_locks_unsafe_for_binlog选项并且事务的隔离级别未设置为SERIALIZABLE,则不指定FOR UPDATE或LOCK IN SHARE MODE.因此,不会对从所选表中读取的行设置锁定.


Not*_*tMe 16

使用

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

5.0版文档在这里.

版本5.1文档在这里.

  • 谢谢,我认为它已经接近了,但是这个声明需要多长时间?我将在PHP程序中使用此语句,并且一旦查询完成,应该最好自动重置TRANSACTION ISOLATION LEVEL (2认同)

zom*_*bat 13

您可能想阅读MySQL手册的这一页.表的锁定方式取决于表的类型.

MyISAM使用表锁来实现非常高的读取速度,但是如果你有一个UPDATE语句在等待,那么将来的SELECTS将在UPDATE后面排队.

InnoDB表使用行级锁定,并且您不会将整个表锁定在UPDATE后面.还有其他与InnoDB相关的锁定问题,但您可能会发现它符合您的需求.

  • *我可以做些什么来避免在MyISAM的情况下SELECTS排队?*切换到innodb.MyISAM对每个查询都使用表级锁.这是它的主要缺陷. (6认同)
  • MyISAM表不支持任何形式的事务.事务查询将在MyISAM表上运行,因此上面提到的查询将执行,但它不起作用. (5认同)