Saya punya permintaan SQL yang sangat sederhana:
SELECT COUNT(DISTINCT x) FROM table;
Meja saya memiliki sekitar 1,5 juta baris. Permintaan ini berjalan sangat lambat; dibutuhkan sekitar 7,5, dibandingkan dengan
SELECT COUNT(x) FROM table;
yang memakan waktu sekitar 435 ms. Apakah ada cara untuk mengubah kueri saya untuk meningkatkan kinerja? Saya sudah mencoba mengelompokkan dan melakukan penghitungan reguler, serta menempatkan indeks pada x; keduanya memiliki waktu eksekusi 7,5s yang sama.
performance
postgresql
count
distinct
ferson2020
sumber
sumber
\d
output daripsql
yang baik) dan tepat kolom yang bermasalah dengan Anda. Akan baik untuk melihatEXPLAIN ANALYZE
kedua pertanyaan.Jawaban:
Anda bisa menggunakan ini:
Ini jauh lebih cepat daripada:
sumber
COUNT(DISTINCT())
melakukan penyortiran, akan sangat membantu untuk memiliki indeks padacolumn_name
terutama dengan jumlah yang relatif kecilwork_mem
(di mana hashing akan menghasilkan jumlah batch yang relatif besar). Karena itu, tidak selalu buruk untuk menggunakan COUNT (DISTINCT () _, bukan?Count(column)
hanya menghitung nilai yang bukan nol.count(*)
menghitung baris. Jadi yang pertama / lebih lama, juga akan menghitung baris nol (sekali). Ubah untukcount(column_name)
membuat mereka berperilaku sama.Hasil:
Rencana yang sama dengan CTE mungkin juga dapat diproduksi dengan metode lain (fungsi jendela)
sumber
Jika Anda
count(distinct(x))
secara signifikan lebih lambat daricount(x)
itu, Anda bisa mempercepat kueri ini dengan mempertahankan jumlah nilai x dalam tabel yang berbeda, misalnyatable_name_x_counts (x integer not null, x_count int not null)
, menggunakan pemicu. Tetapi kinerja penulisan Anda akan menurun dan jika Anda memperbarui beberapax
nilai dalam satu transaksi maka Anda harus melakukan ini dalam urutan eksplisit untuk menghindari kemungkinan kebuntuan.sumber
Saya juga mencari jawaban yang sama, karena pada suatu saat saya membutuhkan total_count dengan nilai yang berbeda bersama dengan limit / offset .
Karena agak sulit untuk dilakukan- Untuk mendapatkan jumlah total dengan nilai yang berbeda bersama dengan batas / offset. Biasanya sulit untuk mendapatkan jumlah total dengan batas / offset. Akhirnya saya mendapatkan cara untuk melakukan -
SELECT DISTINCT COUNT(*) OVER() as total_count, * FROM table_name limit 2 offset 0;
Performa permintaan juga tinggi.
sumber