Kết quả đúng?
Trước hết: tính đúng đắn. Bạn muốn sản xuất một loạt các yếu tố độc đáo? Truy vấn hiện tại của bạn không làm điều đó. Chức năng uniq()
từ mô-đun intarray chỉ hứa hẹn:
loại bỏ các bản sao liền kề
Giống như được hướng dẫn trong hướng dẫn , bạn sẽ cần:
SELECT l.d + r.d, uniq(sort(array_agg_mult(r.arr)))
FROM ...
Cũng cung cấp cho bạn các mảng được sắp xếp - giả sử bạn muốn điều đó, bạn đã không làm rõ.
Tôi thấy bạn có sort()
trong câu đố của bạn , vì vậy đây có thể chỉ là một lỗi đánh máy trong câu hỏi của bạn.
Hậu 9,5
Dù bằng cách nào, bạn sẽ thích Postgres 9.5 mới (hiện đang là beta). Nó cung cấp các khả năng array_agg_mult()
vượt trội và nhanh hơn nhiều:
Cũng đã có những cải tiến hiệu suất khác để xử lý mảng.
Truy vấn
Mục đích chính array_agg_mult()
là tổng hợp các mảng đa chiều, nhưng dù sao bạn cũng chỉ tạo ra các mảng 1 chiều. Vì vậy, tôi ít nhất sẽ thử truy vấn thay thế này:
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;
Điều này cũng giải quyết câu hỏi của bạn:
Hàm tổng hợp có thể loại bỏ các bản sao trực tiếp không?
Vâng, nó có thể, với DISTINCT
. Nhưng điều đó không nhanh hơn so uniq()
với mảng số nguyên, đã được tối ưu hóa cho mảng số nguyên, trong khi đó DISTINCT
là chung cho tất cả các loại dữ liệu đủ điều kiện.
Không yêu cầu intarray
mô-đun. Tuy nhiên , kết quả không nhất thiết phải được sắp xếp. Postgres sử dụng các thuật toán khác nhau cho DISTINCT
(IIRC), các bộ lớn thường được băm, sau đó kết quả không được sắp xếp trừ khi bạn thêm tường minh ORDER BY
. Nếu bạn cần các mảng được sắp xếp, bạn có thể thêm ORDER BY
trực tiếp vào hàm tổng hợp:
array_agg(DISTINCT elem ORDER BY elem)
Nhưng điều đó thường chậm hơn so với việc cung cấp dữ liệu được sắp xếp trước array_agg()
(một loại lớn so với nhiều loại nhỏ). Vì vậy, tôi sẽ sắp xếp trong một truy vấn con và sau đó tổng hợp:
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;
Đây là biến thể nhanh nhất trong thử nghiệm chữ thảo của tôi trên Postgres 9.4.
SQL Fiddle dựa trên cái bạn cung cấp.
Mục lục
Tôi không thấy nhiều tiềm năng cho bất kỳ chỉ số nào ở đây. Tùy chọn duy nhất sẽ là:
CREATE INDEX ON right2 (t1, arr);
Chỉ có ý nghĩa nếu bạn nhận được quét chỉ mục từ điều này - điều này sẽ xảy ra nếu bảng bên dưới right2
rộng hơn đáng kể so với chỉ hai cột này và thiết lập của bạn đủ điều kiện để quét chỉ mục. Chi tiết trong Wiki Postgres.
right2.arr
là NULL như lược đồ demo của bạn gợi ý? Bạn có cần sắp xếp các mảng như kết quả?