我在文档count(*)
中看到和之间的区别count(pk)
。我一直在使用count(pk)
(where pk
is a SERIAL PRIMARY KEY
) 不知道count(*)
.
我的问题是关于 Postgres 的内部优化。是否足够聪明地发现 aSERIAL PRIMARY KEY
将存在于每一行中并且永远不会是错误的并且只计算行数,或者它是否会对每一行进行冗余谓词检查?我同意这可能是一个毫无意义的优化,但我只是好奇。
我查看了EXPLAIN
和EXPLAIN VERBOSE
for的输出count(*)
,看看是否提到检查其输出中的谓词。它没有。count(id)
count(id > 50)
EXPLAIN
我在过去几年对各种版本的反复测试中得到了一致的结果:
count(*)
比count(pk)
. 它也更短,并且大多数时候它更适合测试的内容:一行的存在。关于:
唯一相关的是
NOT NULL
约束。一PRIMARY KEY
列是NOT NULL
自动的。“连续”或“从不假”与问题正交。使用
count(col)
,如果PostgreSQL 试图变得聪明并检查系统目录中的列是否存在NOT NULL
并回退到等价的count(*)
,那么您在系统表上的查找仍然比使用 多一次count(*)
。更重要的是,任何列都可以
NULL
在OUTER JOIN
. 所以优化不适用于某些查询。可能不值得复杂...至于
EXPLAIN
输出,有一个提示:意思是,即使定义了,
count(col)
也不会转换为.count(*)
NOT NULL