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 VIEW
dengan data pra-agregat darimeta
, jika data Anda tidak berubah (banyak). - CTE rekursif yang meniru pemindaian indeks longgar untuk besar
meta
tabel dengan banyak baris per produk (relatif sedikitproduct_id
yang berbeda ).
Ini adalah satu-satunya cara yang saya tahu untuk menggunakan indeks untuk kueri BERBEDA di seluruh tabel.