Postgres:count(*)とcount(id)


11

私が見た中でのドキュメントの違いをcount(*)してcount(pk)。の存在を知らないままcount(pk)pkSERIAL PRIMARY KEY)を使用していたcount(*)

私の質問はPostgresの内部最適化についてです。SERIAL PRIMARY KEYすべての行にa が存在し、偽になることはなく、行をカウントするだけであることをピックアップするのに十分スマートですか?それとも各行に対して冗長な述語チェックを行いますか?これはおそらく無意味な最適化では多すぎると私は同意しますが、私は興味があるだけです。

私はの出力で見ていたEXPLAINEXPLAIN VERBOSEのためにcount(*)count(id)そしてcount(id > 50)かどうかを確認するためにEXPLAIN、その出力に述語をチェック述べました。そうではありません。

回答:


15

私は最後の年にわたってさまざまなバージョンと私の繰り返しテストで一貫性のある結果を得た:
count(*)ある少し速くよりcount(pk)。また、これは短く、ほとんどの場合、テストされているもの、つまり行の存在により適しています。

について:

Postgres SERIAL PRIMARY KEYは、すべての行にa が存在することを認識し、決してfalseにならないように十分スマートです。

関連する唯一のものはNOT NULL制約です。PRIMARY KEYNOT NULL、自動的に、serialまたはnever false質問に直交しています。

を使用してcount(col)、PostgreSQLがスマートになり、システムカタログで列が同等であるかどうかを確認しようとした場合でも、システムテーブルでのルックアップは、を使用した場合よりも1つ多くなります。NOT NULLcount(*)count(*)

用としてEXPLAIN出力、そこにあるヒントは:

EXPLAIN SELECT count(*) FROM ...

Aggregate  (cost=4963.38..4963.43 rows=1 width=0) ...


EXPLAIN SELECT count(pk) FROM ...

Aggregate  (cost=4963.38..4963.43 rows=1 width=4) ...

定義されていても、count(col)はに変換されませんcount(*)NOT NULL


これはまだ新しいバージョンの場合ですか?私はそれが実際にすべてのクエリの検索を必要としないだろうと思います-それはキャッシュすることができます。
OndraŽižka18年

1
ところで、NOT NULL列の場合、行数が多いと違いが大きくなります。数百万行の場合、COUNT(*)3倍高速です。(Postgres 9.4)
OndraŽižka18年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.