阅读关于EXPLAIN
命令的article,我遇到了所谓的invisible rows
概念。对我来说更具体:
在顺序扫描中,执行者需要:
- 阅读关系foo的所有块
- 检查每个区块中的每一行,以过滤“ 不可见 ”行
使用Google搜索invisible row postgresql和与之相关的一些内容并没有给出任何有用的结果。那么,这个概念意味着什么?或者它是一个非正式的概念,并没有标准化。
答案 0 :(得分:2)
由于事务隔离,并非所有事务都可以看到所有元组。你应该检查manual on MVCC。对于所有更复杂的概念,源代码也是great source,this 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'
您可以很容易地看到,如果T1
在T2
之前结束,则其结果将是数字X:名称为John的用户数。
但如果T1
在T2
之后结束,则结果值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的物理实现必须处理这种情况,以便产生正确的结果。