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

Dampak kinerja tampilan pada fungsi agregat vs batasan kumpulan hasil

Kueri tidak sama persis

Untuk memperjelas konteksnya:

  • max(id) tidak termasuk NULL nilai-nilai. Tapi ORDER BY ... LIMIT 1 tidak.
  • NULL nilai mengurutkan terakhir dalam urutan menaik, dan pertama dalam menurun. Jadi Index Scan Backward mungkin tidak menemukan nilai terbesar (menurut max() ) pertama, tetapi sejumlah NULL nilai.

Persamaan formal dari:

SELECT max(id) FROM testview;

bukan:

SELECT id FROM testview ORDER BY id DESC LIMIT 1;

tapi:

SELECT id FROM testview ORDER BY id DESC NULLS LAST LIMIT 1;

Kueri terakhir tidak mendapatkan paket kueri cepat. Tapi itu akan dengan indeks dengan urutan pengurutan yang cocok:(id DESC NULLS LAST) .

Itu berbeda untuk fungsi agregat min() dan max() . Mereka mendapatkan paket cepat saat menargetkan tabel test1 langsung menggunakan indeks PK biasa di (id) . Tetapi tidak jika berdasarkan tampilan (atau kueri gabungan yang mendasarinya secara langsung - tampilan bukanlah pemblokir). Pengurutan indeks nilai NULL di tempat yang tepat hampir tidak berpengaruh.

Kami ketahuilah bahwa id dalam kueri ini tidak akan pernah bisa NULL . Kolom didefinisikan NOT NULL . Dan gabungan dalam tampilan secara efektif merupakan INNER JOIN yang tidak dapat memperkenalkan NULL nilai untuk id .
Kami ketahui juga bahwa indeks pada test.id tidak dapat berisi nilai NULL.
Tetapi perencana kueri Postgres bukanlah AI. (Tidak juga, itu bisa lepas kendali dengan cepat.) Saya melihat dua kekurangan :

  • min() dan max() dapatkan paket cepat hanya ketika menargetkan tabel, terlepas dari urutan pengurutan indeks, kondisi indeks ditambahkan:Index Cond: (id IS NOT NULL)
  • ORDER BY ... LIMIT 1 dapatkan paket cepat hanya dengan urutan pengurutan indeks yang sama persis.

Tidak yakin, apakah itu dapat ditingkatkan (dengan mudah).

db<>fiddle di sini - mendemonstrasikan semua hal di atas

Indeks

Indeks ini sama sekali tidak berguna:

CREATE INDEX ON "test" ("id");

PK di test.id diimplementasikan dengan indeks unik pada kolom, yang sudah mencakup semua yang mungkin dilakukan indeks tambahan untuk Anda.

Mungkin masih ada lagi, menunggu pertanyaan selesai.

Kasus uji terdistorsi

Kasus uji terlalu jauh dari kasus penggunaan yang sebenarnya untuk menjadi bermakna.

Dalam pengaturan pengujian, setiap tabel memiliki 100 ribu baris, tidak ada jaminan bahwa setiap nilai dalam joincol memiliki kecocokan di sisi lain, dan kedua kolom bisa NULL

Kasing asli Anda memiliki 10 juta baris di table1 dan <100 baris di table2 , setiap nilai dalam table1.joincol memiliki kecocokan di table2.joincol , keduanya didefinisikan NOT NULL , dan table2.joincol unik. Hubungan klasik satu-ke-banyak. Harus ada UNIQUE batasan pada table2.joincol dan batasan FK t1.joincol --> t2.joincol .

Tapi itu saat ini semua terpelintir dalam pertanyaan. Berdiri sampai itu dibersihkan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Driver:[email protected] mengembalikan null untuk URL... Saat menerapkan boot musim semi ke Heroku

  2. Django JSONField

  3. Cara mudah untuk membuat tipe pengembalian menjadi tabel SETOF plus bidang tambahan?

  4. Daftar pengguna PostgreSQL

  5. Mengakses file XML eksternal sebagai variabel dalam skrip PSQL (bersumber dari skrip bash)