Doğru sonuçlar?
İlk önce: doğruluk. Bir dizi benzersiz eleman mı üretmek istiyorsunuz? Mevcut sorgunuz bunu yapmıyor. Fonksiyon uniq()
gelen intarray modülüne sadece vaat:
bitişik kopyaları kaldır
Gibi Kılavuzda , ihtiyacınız olacaktır:
SELECT l.d + r.d, uniq(sort(array_agg_mult(r.arr)))
FROM ...
Ayrıca sıralı diziler verir - bunu istediğinizi varsayarsak, netleştirmediniz.
Görmeni var sort()
senin keman içinde bu sadece sorunuzun bir yazım hatası olabilir, böylece.
Postgres 9.5
Her iki durumda da , yeni Postgres 9.5'i (şu anda beta) seveceksiniz . Bu yeteneklerini sağlar array_agg_mult()
çok daha hızlı kutunun çıkışı ve:
Dizi işleme için başka performans geliştirmeleri de yapılmıştır.
Sorgu
Temel amacı array_agg_mult()
çok boyutlu dizileri birleştirmektir, ancak yine de yalnızca 1 boyutlu diziler üretiyorsunuz. Yani en azından bu alternatif sorguyu denemek istiyorum:
SELECT l.d + r.d AS d_sum, array_agg(DISTINCT elem) AS result_arr
FROM left2 l
JOIN right2 r USING (t1)
, unnest(r.arr) elem
GROUP BY 1
ORDER BY 1;
Ayrıca sorunuzu da yanıtlar:
Toplama işlevi kopyaları doğrudan kaldırabilir mi?
Evet, yapabilir DISTINCT
. Ancak bu uniq()
, tam sayı dizileri için optimize edilmiş tam sayı dizilerinden daha hızlı değildir , ancak DISTINCT
tüm niteleyici veri türleri için geneldir.
intarray
Modül gerektirmez . Ancak , sonuç mutlaka sıralanmaz. Postgres, DISTINCT
(IIRC) için değişken algoritmalar kullanır , büyük kümeler genellikle karmadır, sonra açık eklemediğiniz sürece sonuç sıralanmaz ORDER BY
. Eğer sıralı diziler gerekiyorsa, olabilir eklemek ORDER BY
doğrudan agrega işlevine:
array_agg(DISTINCT elem ORDER BY elem)
Ancak bu genellikle önceden sıralanmış verileri beslemekten daha yavaştırarray_agg()
(bir çok çeşit ve birçok küçük çeşit). Bu yüzden bir alt sorgu sıralamak ve daha sonra toplamak:
SELECT d_sum, uniq(array_agg(elem)) AS result_arr
FROM (
SELECT l.d + r.d AS d_sum, elem
FROM left2 l
JOIN right2 r USING (t1)
, unnest(r.arr) elem
ORDER BY 1, 2
) sub
GROUP BY 1
ORDER BY 1;
Postgres 9.4'teki üstünkörü testimdeki en hızlı varyanttı.
Sağladığınız SQL Fiddle .
indeks
Burada herhangi bir dizin için fazla potansiyel görmüyorum. Tek seçenek:
CREATE INDEX ON right2 (t1, arr);
Yalnızca bununla ilgili yalnızca dizin taramaları alırsanız mantıklıdır - temel tablo right2
yalnızca bu iki sütundan daha genişse ve kurulumunuz yalnızca dizin taramaları için uygunsa gerçekleşir . Ayrıntılar Postgres Wiki'deki.
right2.arr
Demo şemanızın önerdiği gibi NULL olabilir mi? Sonuç olarak sıralı dizilere mi ihtiyacınız var?