PostgreSQL: COUNT (*) menggunakan pemindaian berurutan, bukan indeks

12

Mengapa PostgreSQL memindai tabel secara berurutan untuk COUNT(*)permintaan, sementara ada kunci primer yang sangat kecil dan terindeks?

Adam Matan
sumber

Jawaban:

15

The halaman wiki resmi memberikan jawaban untuk itu:

[...] Alasan mengapa ini lambat terkait dengan implementasi MVCC di PostgreSQL. Fakta bahwa banyak transaksi dapat melihat status data yang berbeda berarti bahwa tidak ada cara langsung untuk "COUNT (*)" untuk merangkum data di seluruh tabel; PostgreSQL harus berjalan di semua baris, dalam arti tertentu. Ini biasanya menghasilkan pemindaian berurutan yang membaca informasi tentang setiap baris dalam tabel. [...]

Selanjutnya, Anda bisa mencoba ANALYZE untuk membangun kembali info untuk perencana permintaan.

Anda harus mendapatkan kinerja yang lebih baik menggunakan COUNT(an uniquly indexed field)tetapi jika ini sangat besar, pemindaian seq adalah satu-satunya cara untuk melakukannya.

Jika Anda membutuhkan angka yang sangat cepat dan tidak takut menanyakan skema, Anda dapat melakukan hal berikut

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

Tetapi jangan mengandalkan nilai-nilai ini karena ini hanya jumlah "diperkirakan" (walaupun sering kali tepat) dari tupel dalam tabel.

DrColossos
sumber
Saya pikir ini tidak benar. Saya belum membaca apa pun di mana pun, di mana COUNT(pk)akan meningkatkan kinerja. Saya pikir itu akan selalu melakukan pemindaian seq
vol7ron
1
Tanpa klausa mana Anda benar, pemindaian seq akan dilakukan. Dengan pemilihan yang cukup di mana klausa postgresql BISA menggunakan indeks, tetapi perlu diingat itu AKAN kembali ke meja untuk memverifikasi visibilitas tuple yang dilaporkannya.
Scott Marlowe