似乎 mysql 选择内容(与例如计数相反)查询总是至少在 myisam 表上占用一个表读取锁,在 innodb 表上占用一个行读取锁。有没有办法在 mysql 中发出选择内容查询(如果需要,我可以更改表类型)而无需获取任何锁?我不介意返回的数据是否不一致,因为我会将它用于搜索索引。
2 回答
使用InnoDB,您可以通过将事务隔离级别设置为:READ UNCOMMITTED
.
在这个隔离级别:
SELECT 语句以非锁定方式执行,但可能会使用行的早期版本。因此,使用这个隔离级别,这样的读取是不一致的。这也称为“脏读”。否则,此隔离级别的工作方式类似于 READ COMMITTED。
您可以从 MySQL 选项文件更改默认事务隔离级别,或者可以为单个会话启用和禁用它:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM table_name;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
进一步阅读:MySQL 文档:设置事务
在没有 LOCK TABLES 的情况下,myisam 应该相当于读取未提交模式,但它实际上并不支持任何事务类型...
innodb 默认以“一致读取”模式(在“可重复读取”隔离级别)运行,文档建议不会锁定:
如果事务隔离级别为 REPEATABLE READ(默认级别),则同一事务中的所有一致性读取都会读取该事务中第一次此类读取所建立的快照
...
一致读取是 InnoDB 在 READ COMMITTED 和 REPEATABLE READ 隔离级别处理 SELECT 语句的默认模式。一致读取不会对其访问的表设置任何锁定,因此其他会话可以在对表执行一致读取的同时自由修改这些表。
...
如果 innodb_locks_unsafe_for_binlog 选项设置和事务的隔离级别未设置为 SERIALIZABLE。因此,不会对从选定表读取的行设置任何锁。
http://dev.mysql.com/doc/refman/5.0/en/innodb-consistent-read.html