Postgres: count (*) vs count (id)


11

ผมเห็นในเอกสารความแตกต่างระหว่างและcount(*) count(pk)ผมเคยใช้count(pk)(ที่pkเป็นSERIAL PRIMARY KEY) count(*)ไม่ทราบว่าเกี่ยวกับการดำรงอยู่ของ

คำถามของฉันเกี่ยวกับการเพิ่มประสิทธิภาพภายในของ Postgres มันฉลาดพอที่จะรับได้หรือไม่ว่าSERIAL PRIMARY KEYจะมีอยู่ในทุกแถวและไม่ผิดและนับจำนวนแถวหรือจะตรวจสอบคำกริยาซ้ำซ้อนสำหรับแต่ละแถวหรือไม่ ฉันยอมรับว่านี่อาจเป็นการเพิ่มประสิทธิภาพที่ไม่มีจุดหมายมากเกินไป แต่ฉันแค่อยากรู้

ผมเอามาดูที่การส่งออกของได้EXPLAINและEXPLAIN VERBOSEสำหรับcount(*), count(id)และcount(id > 50)เพื่อดูว่าEXPLAINกล่าวถึงการตรวจสอบภาคในการส่งออกของตน มันไม่ได้

คำตอบ:


15

ผมได้รับผลที่สอดคล้องกันในการทดสอบซ้ำแล้วซ้ำอีกของฉันกับรุ่นต่าง ๆ ในช่วงหลายปีที่ผ่านมา:
count(*)เป็นเล็กน้อยcount(pk)เร็วกว่า มันสั้นลงและส่วนใหญ่เวลาเหมาะกับสิ่งที่ทดสอบ: การมีอยู่ของแถว

เกี่ยวกับ:

Postgres ฉลาดพอที่จะรับได้หรือไม่ว่าSERIAL PRIMARY KEYจะมีอยู่ในทุกแถวและจะไม่ผิดพลาด

สิ่งเดียวที่เกี่ยวข้องคือNOT NULLข้อ จำกัด PRIMARY KEYเป็นNOT NULLโดยอัตโนมัติserialหรือnever falseเป็นมุมฉากกับคำถาม

ด้วยcount(col), ถ้า PostgreSQL ได้พยายามที่จะเป็นสมาร์ทแคตตาล็อกและตรวจสอบระบบไม่ว่าจะเป็นคอลัมน์NOT NULLและถอยกลับไปเทียบเท่าคุณจะยังคงมีอีกหนึ่งมองขึ้นบนโต๊ะระบบกว่าด้วยcount(*)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žka

1
Btw กับNOT NULLคอลัมน์ความแตกต่างใหญ่ถ้าคุณมีจำนวนมากแถว ในกรณีของเรามีแถวนับล้านแถวCOUNT(*)จะเร็วขึ้น 3 เท่า (Postgres 9.4)
Ondra Žižka
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.