postgresql中哪些是不可见的行?

时间:2015-10-02 07:32:03

标签: sql postgresql

阅读关于EXPLAIN命令的article,我遇到了所谓的invisible rows概念。对我来说更具体:

  

在顺序扫描中,执行者需要:

     
      
  • 阅读关系foo的所有块
  •   
  • 检查每个区块中的每一行,以过滤“ 不可见 ”行
  •   

使用Google搜索invisible row postgresql和与之相关的一些内容并没有给出任何有用的结果。那么,这个概念意味着什么?或者它是一个非正式的概念,并没有标准化。

3 个答案:

答案 0 :(得分:2)

由于事务隔离,并非所有事务都可以看到所有元组。你应该检查manual on MVCC。对于所有更复杂的概念,源代码也是great sourcethis description似乎可以很好地解释它。

特别是

答案 1 :(得分:2)

这基本上是MVCC和交易的结果。如果启动事务,那么在事务运行之前,会话通常不会显示由其他会话创建的行。这是为了防止事务状态在执行期间变得不一致。

有与唯一索引和键列相关的异常,但遇到这些异常的情况相对较少,特别是如果所有主键都是SERIAL的话。

答案 2 :(得分:1)

不可见行是在启动时对事务不可见的行(让我们称之为T1)。

典型情况如下:

事务T2开始执行。 T2包含在查询

UPDATE users SET name = 'John' WHERE age < 18

同时,事务T1(与T2同时)开始执行,执行以下操作:

SELECT COUNT(*) FROM users WHERE name = 'John'

您可以很容易地看到,如果T1T2之前结束,则其结果将是数字X:名称为John的用户数。

但如果T1T2之后结束,则结果值X可能会有所不同(如果存在满足WHERE谓词的某些行,则会出现这种情况)。

同样的事情可能发生在JOIN中,生成的连接关系应该包含​​或不包含满足连接谓词的行。

考虑交易T1

SELECT * FROM users u, infos i INNER JOIN u.id = info.id;

同时执行T2

UPDATE infos SET id = 9 WHERE id > 12

逻辑运算符JOIN的物理实现必须处理这种情况,以便产生正确的结果。