올바른 결과?
우선 : 정확성. 독특한 요소의 배열을 만들고 싶습니까? 현재 쿼리는 그렇게하지 않습니다. intarray 모듈 의 기능 uniq()
은 다음을 약속합니다.
인접한 중복 제거
마찬가지로 설명서에 지시 , 당신은해야합니다 :
SELECT l.d + r.d, uniq(sort(array_agg_mult(r.arr)))
FROM ...
또한 정렬 된 배열을 제공합니다. 원한다고 가정하면 명확하지 않습니다.
나는 당신 이 sort()
당신의 바이올린에 있는 것을 보았 으므로 이것은 당신의 질문에 오타 일 수 있습니다.
포스트그레스 9.5
어느 쪽이든, 당신은 새로운 Postgres 9.5 (현재 베타)를 좋아할 것 입니다. array_agg_mult()
즉시 사용 가능한 기능을 제공 하며 훨씬 더 빠릅니다.
어레이 처리를위한 다른 성능 개선 사항도 있습니다.
질문
주요 목적은 array_agg_mult()
다차원 배열을 집계하는 것이지만 어쨌든 1 차원 배열 만 생성합니다. 그래서 나는 적어도이 대안 쿼리를 시도 할 것입니다 :
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;
또한 귀하의 질문을 해결합니다.
집계 함수가 중복을 직접 제거 할 수 있습니까?
그렇습니다 DISTINCT
. 그러나 uniq()
정수 배열에 대해 최적화 된 정수 배열 보다 빠르지는 않지만 DISTINCT
모든 적격 데이터 유형에 일반적입니다.
intarray
모듈이 필요하지 않습니다 . 그러나 결과가 반드시 정렬되지는 않습니다. Postgres는 DISTINCT
(IIRC)에 대해 다양한 알고리즘을 사용 하고 큰 세트는 일반적으로 해시 된 다음 explicit 추가하지 않으면 결과가 정렬되지 않습니다 ORDER BY
. 정렬 된 배열이 필요한 경우 집계 함수에 직접 추가 할 수 있습니다 ORDER BY
.
array_agg(DISTINCT elem ORDER BY elem)
그러나 일반적으로 사전 정렬 된 데이터를 하나의 큰 정렬 대 많은 작은 정렬에 공급하는 것보다 느립니다array_agg()
. 따라서 하위 쿼리를 정렬 한 다음 집계합니다.
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의 커서 테스트에서 가장 빠른 변형이었습니다.
제공 한 것을 기반으로하는 SQL Fiddle .
인덱스
나는 여기에 어떤 인덱스에 대한 많은 잠재력을 보지 못한다. 유일한 옵션은 다음과 같습니다.
CREATE INDEX ON right2 (t1, arr);
이 중에서 인덱스 전용 스캔을 얻는 경우에만 의미가 있습니다. 기본 테이블 right2
이이 두 열보다 실질적으로 넓고 설정이 인덱스 전용 스캔에 적합한 경우에 발생합니다. Postgres Wiki의 세부 사항.
right2.arr
데모 스키마가 제안한 것처럼 NULL 일 수 있습니까 ? 결과적으로 정렬 된 배열이 필요합니까?