一尘不染

这会锁定数据库吗?

sql

insert into test.qvalues 
  select * from qcvalues.qvalues;

我想知道如果上面的行锁定了数据库QCVALUES


阅读 90

收藏
2021-05-16

共1个答案

一尘不染

对我而言,文档尚不清楚:

内部锁定方法建议在某些情况下,有可能在另一个会话正在从中读取时将其插入MyISAM表:

MyISAM存储引擎支持并发插入,以减少给定表的读写器之间的争用:如果MyISAM表在数据文件的中间没有空闲块,则总是在数据文件的末尾插入行。在这种情况下,您可以自由混合MyISAM表的并发INSERT和SELECT语句,而无需锁定。也就是说,您可以在其他客户端读取表的同时,将行插入MyISAM表中。漏洞可能是由于表格中间的行已删除或更新而造成的。如果有孔,将禁用并发插入,但是当所有孔都已填充新数据时,并发插入会自动重新启用。

但是,“表锁定问题”显示了在SELECT完成之前表将被锁定的情况(这符合您的情况):

在以下情况下,表锁定也是不利的:

  • 会话发出一个需要很长时间才能运行的SELECT。
  • 然后,另一个会话在同一表上发出UPDATE。该会话等待直到SELECT完成。
    * 另一个会话在同一表上发出另一个SELECT语句。因为UPDATE具有比SELECT更高的优先级,所以此SELECT在等待第一个SELECT完成之后等待UPDATE完成。

InnoDB表实现了行级锁定,因此将仅锁定正在读取的行,而不是整个表。

我不仅仅是依靠文档,还尝试了一些测试:

  1. 创建具有相同结构的两个表:table_atable_b
  2. 填充table_a500,000行。
  3. 使用语句将数据从复制table_a到。table_b``INSERT INTO ... SELECT
  4. 在复制过程中,请使用另一个会话将新行插入table_a
  5. 检查是否table_b包含新记录。

当两个表都在MyISAM所在的位置时,table_b复制后不包含新记录。当两个表都在InnoDB中时,table_b确实在复制后包含新记录。我已经重复了三遍,并且正如预期的那样,每次的结果都是相同的。

因此,简而言之,如果您的表是MyISAM,它将被锁定。如果是InnoDB,则不会。当然,此测试不考虑更新,但是我希望结果会相似。

2021-05-16