Saat mengambil semua atau sebagian besar baris dari tabel, cara tercepat untuk jenis kueri ini biasanya adalah dengan menggabungkan / memisahkan pertama dan bergabunglah nanti :
SELECT *
FROM products p
JOIN (
SELECT DISTINCT ON (product_id) *
FROM meta
ORDER BY product_id, id DESC
) m ON m.product_id = p.id;
Semakin banyak baris di meta per baris di products , semakin besar dampaknya terhadap kinerja.
Tentu saja, Anda ingin menambahkan ORDER BY klausa dalam subquery mendefinisikan yang baris untuk memilih bentuk setiap set dalam subquery. @Craig dan @Clodoaldo sudah memberi tahu Anda tentang itu. Saya mengembalikan meta baris dengan id tertinggi .
SQL Fiddle.
Detail untuk DISTINCT ON :
- Pilih baris pertama di setiap grup GROUP BY?
Optimalkan kinerja
Namun, ini tidak selalu merupakan solusi tercepat. Bergantung pada distribusi data, ada berbagai gaya kueri lainnya. Untuk kasus sederhana yang melibatkan gabungan lain, yang ini berjalan jauh lebih cepat dalam pengujian dengan tabel besar:
SELECT p.*, sub.meta_id, m.product_id, m.price, m.flag
FROM (
SELECT product_id, max(id) AS meta_id
FROM meta
GROUP BY 1
) sub
JOIN meta m ON m.id = sub.meta_id
JOIN products p ON p.id = sub.product_id;
Jika Anda tidak ingin menggunakan id non-deskriptif sebagai nama kolom, kami tidak akan mengalami tabrakan penamaan dan cukup menulis SELECT p.*, m.* . (Saya tidak pernah gunakan id sebagai nama kolom.)
Jika kinerja adalah persyaratan terpenting Anda, pertimbangkan opsi lainnya:
- sebuah
MATERIALIZED VIEWdengan data pra-agregat darimeta, jika data Anda tidak berubah (banyak). - CTE rekursif yang meniru pemindaian indeks longgar untuk besar
metatabel dengan banyak baris per produk (relatif sedikitproduct_idyang berbeda ).
Ini adalah satu-satunya cara yang saya tahu untuk menggunakan indeks untuk kueri BERBEDA di seluruh tabel.