PostgreSQL: COUNT (*) ใช้การสแกนตามลำดับไม่ใช่ดัชนี


12

เหตุใด PostgreSQL จึงสแกนตารางเพื่อCOUNT(*)สอบถามตามลำดับในขณะที่มีคีย์หลักขนาดเล็กและจัดทำดัชนีไว้

คำตอบ:


16

หน้าวิกิพีเดียอย่างเป็นทางการให้คำตอบว่า:

[... ] เหตุผลที่ทำให้สิ่งนี้ช้าเกี่ยวข้องกับการใช้งาน MVCC ใน PostgreSQL ความจริงที่ว่าการทำธุรกรรมหลายรายการสามารถดูสถานะของข้อมูลที่แตกต่างกันหมายความว่าจะไม่มีทางตรงไปตรงมาสำหรับ "COUNT (*)" เพื่อสรุปข้อมูลทั่วทั้งตาราง PostgreSQL ต้องผ่านทุกแถวในบางกรณี ซึ่งตามปกติแล้วจะส่งผลให้ข้อมูลการสแกนตามลำดับอ่านเกี่ยวกับทุกแถวในตาราง [ ... ]

นอกจากนี้คุณสามารถลองวิเคราะห์เพื่อสร้างข้อมูลสำหรับตัวสร้างแบบสอบถามอีกครั้ง

คุณควรใช้ประสิทธิภาพที่ดีขึ้นCOUNT(an uniquly indexed field)แต่ถ้านี่ใหญ่มากการสแกน seq เป็นวิธีเดียวที่จะทำได้

หากคุณต้องการตัวเลขที่รวดเร็วมากและไม่กลัวที่จะสืบค้นสคีมาคุณสามารถทำสิ่งต่อไปนี้

SELECT reltuples FROM pg_class WHERE oid = 'your_table'::regclass

แต่ไม่ต้องพึ่งพาค่านี้เนื่องจากเป็นเพียงค่า "tuples" (แม้ว่าบ่อยครั้งจะถูกต้อง) ในตาราง


ฉันไม่คิดว่ามันถูกต้อง ฉันไม่ได้อ่านอะไรเลยที่ไหนCOUNT(pk)จะปรับปรุงประสิทธิภาพ ฉันคิดว่ามันจะทำการสแกน seq เสมอ
vol7ron

1
หากไม่มีส่วนที่คุณถูกต้องการสแกน seq จะถูกดำเนินการ ด้วยการเลือกที่เพียงพอที่ข้อ postgresql สามารถใช้ดัชนีได้ แต่โปรดจำไว้ว่ามันจะกลับไปที่ตารางเพื่อตรวจสอบการแสดงผลของสิ่งอันดับที่รายงาน
Scott Marlowe

EXPLAIN SELECT * from your_table;อีกวิธีหนึ่งที่จะได้รับจำนวนแถวที่คาดกันว่าผมพบว่าง่ายต่อการจดจำคือ สิ่งนี้จะไม่ดำเนินการค้นหา เอาต์พุตรวมถึงrows=…จำนวนแถวโดยประมาณ
Sven Marnach
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.