Postgres: count (*) - count (id)


11

Ben gördüğüm belgelere arasındaki farkı count(*)ve count(pk). Ben kullanarak olmuştu count(pk)(burada pkbir olduğunu SERIAL PRIMARY KEYvarlığı hakkında bilmeden) değil count(*).

Sorum Postgres'in dahili optimizasyonları hakkında. SERIAL PRIMARY KEYHer satırda a'nın var olacağını ve asla yanlış olmayacağını ve sadece satırları sayacağını alacak kadar akıllı mı yoksa her satır için fazladan yüklem kontrolleri yapacak mı? Bunun muhtemelen anlamsız bir optimizasyon olduğunu kabul ediyorum, ama sadece merak ediyorum.

Ben çıkışında bir göz attım EXPLAINve EXPLAIN VERBOSEiçin count(*), count(id)ve count(id > 50)görmek için EXPLAINonun çıktıda yüklemler kontrol bahsetti. Öyle değil.

Yanıtlar:


15

Geçen yıllar boyunca çeşitli versiyonlarıyla benim tekrarlanan testlerde tutarlı sonuçlar aldık:
count(*)olduğu biraz daha hızlı count(pk). Ayrıca daha kısadır ve çoğu zaman test edilene daha iyi uyar: bir sıranın varlığı.

Hakkında:

Postgres, a'nın SERIAL PRIMARY KEYher satırda var olacağını ve asla yanlış olmayacağını alacak kadar akıllı mı?

İlgili tek şey NOT NULLkısıtlamadır. PRIMARY KEYOlduğu NOT NULLotomatik serialveya never falsesoruya diktir.

İle count(col), eğer PostgreSQL akıllı olmak ve bir sütun olup olmadığını sistem katalog kontrol etmeye çalışıyordu NOT NULLve eşdeğeri geri düşmek count(*), hala bir tane daha göz-up sistem masada ile daha olurdu count(*).

Gelince EXPLAINçıkışı, orada olan bir ipucu:

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) ...

Anlam, count(col)bir değil dönüştürülür count(*)onu tanımlanan bile NOT NULL.


Yeni sürümlerde durum hala böyle mi? Gerçekten her sorgu için bir arama gerekmez olmaz - önbelleğe alınabilir.
Ondra Aprižka

1
Btw, bir NOT NULLsütunla, çok sayıda satırınız varsa fark büyüktür . Milyonlarca satırlı durumumuzda COUNT(*), 3 kat daha hızlıdır. (Postgres 9.4)
Ondra Aprižka
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.