PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Cara terbaik untuk mendapatkan jumlah hasil sebelum LIMIT diterapkan

SQL Murni

Hal-hal telah berubah sejak 2008. Anda dapat menggunakan fungsi jendela untuk mendapatkan hitungan lengkap dan hasil terbatas dalam satu kueri. Diperkenalkan dengan PostgreSQL 8.4 pada tahun 2009.

SELECT foo
     , count(*) OVER() AS full_count
FROM   bar
WHERE  <some condition>
ORDER  BY <some col>
LIMIT  <pagesize>
OFFSET <offset>;

Perhatikan bahwa ini bisa jauh lebih mahal daripada tanpa jumlah total . Semua baris harus dihitung, dan kemungkinan jalan pintas yang hanya mengambil baris teratas dari indeks yang cocok mungkin tidak membantu lagi.
Tidak terlalu penting dengan tabel kecil atau full_count <=OFFSET + LIMIT . Penting untuk full_count yang jauh lebih besar .

Kasus sudut :ketika OFFSET setidaknya sama dengan jumlah baris dari kueri dasar, tidak ada baris dikembalikan. Jadi Anda juga tidak mendapatkan full_count . Alternatif yang memungkinkan:

  • Jalankan kueri dengan LIMIT/OFFSET dan dapatkan juga jumlah total baris

Urutan peristiwa dalam SELECT permintaan

(0. CTE dievaluasi dan dimaterialisasikan secara terpisah. Dalam Postgres 12 atau yang lebih baru, perencana dapat menyejajarkan subkueri seperti itu sebelum mulai bekerja.) Tidak di sini.

  1. WHERE klausa (dan JOIN kondisi, meskipun tidak ada dalam contoh Anda) memfilter baris yang memenuhi syarat dari tabel dasar. Selebihnya didasarkan pada subkumpulan yang difilter.

( 2. GROUP BY dan fungsi agregat akan ada di sini.) Tidak di sini.

( 3. SELECT lainnya ekspresi daftar dievaluasi, berdasarkan kolom yang dikelompokkan / dikumpulkan.) Tidak di sini.

  1. Fungsi jendela diterapkan tergantung pada OVER klausa dan spesifikasi bingkai fungsi. Sederhana count(*) OVER() didasarkan pada semua baris kualifikasi.

  2. ORDER BY

( 6. DISTINCT atau DISTINCT ON akan pergi ke sini.) Tidak di sini.

  1. LIMIT / OFFSET diterapkan berdasarkan urutan yang ditetapkan untuk memilih baris yang akan dikembalikan.

LIMIT / OFFSET menjadi semakin tidak efisien dengan semakin banyaknya baris dalam tabel. Pertimbangkan pendekatan alternatif jika Anda membutuhkan kinerja yang lebih baik:

  • Optimalkan kueri dengan OFFSET di meja besar

Alternatif untuk mendapatkan hitungan akhir

Ada pendekatan yang sangat berbeda untuk mendapatkan jumlah baris yang terpengaruh (tidak hitungan lengkap sebelum OFFSET &LIMIT diterapkan). Postgres memiliki pembukuan internal berapa banyak baris yang dipengaruhi oleh perintah SQL terakhir. Beberapa klien dapat mengakses informasi tersebut atau menghitung baris sendiri (seperti psql).

Misalnya, Anda dapat mengambil jumlah baris yang terpengaruh di plpgsql segera setelah menjalankan perintah SQL dengan:

GET DIAGNOSTICS integer_var = ROW_COUNT;

Detail dalam manual.

Atau Anda dapat menggunakan pg_num_rows di PHP . Atau fungsi serupa di klien lain.

Terkait:

  • Menghitung jumlah baris yang terpengaruh oleh kueri batch di PostgreSQL


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pustaka tidak dimuat:/usr/local/opt/readline/lib/libreadline.6.2.dylib

  2. Bagaimana cara mendapatkan min, median, dan maks dari kueri saya di postgresql?

  3. PostgreSQL mengonversi kolom menjadi baris? Mengubah urutan?

  4. Apa indeks yang tepat untuk menanyakan struktur dalam array di Postgres jsonb?

  5. Pembuatan data dan kualitas perangkat keras