두 개의 테이블에있는 연산자 A
및 B
을 사용하는 간단한 2 단계 SQL 쿼리가 있습니다. 하위 선택을 사용하여 외래 키로 저장된 테이블 A
의 ID 수를 검색합니다. B, 테이블 B에 대한 (가능하면 복잡한) u 리 (및 기타 조인 된 테이블)를 사용합니다. 그런 다음 첫 번째 x
ID를 A
으로 간단하게 반환하고 싶습니다. 포스트 그레스가 제한되기 전에 설정 전체 결과에 GROUP BY
/DISTINCT
작업을 수행 보인다 매우 느린증분 DISTINCT/GROUP BY 연산
SELECT sq.id
FROM (
SELECT a_id AS id, created_at
FROM B
WHERE ...
ORDER BY created_at DESC
) sq
GROUP BY sq.id
ORDER BY max(sq.created_at) DESC
LIMIT 10;
을 :이 같은 쿼리를 사용했습니다. 하위 쿼리 (예 : 100)가 LIMIT
인 경우 성능은 좋아질 뿐이지 만 (결과적으로 sq
의 결과 행에 적어도 10 개의 별개의 값이 있음을 보장하지 않습니다. 포스트 그레스는 대신에 (기존) 인덱스를 사용 B
에 순차 검색을 수행 할 것으로 보인다 마찬가지로
쿼리
SELECT a_id AS id
FROM B
WHERE ...
GROUP BY id
ORDER BY max(created_at) DESC
LIMIT 10
는 매우 느립니다. GROUP BY
절을 제거하면 색인이 잘 사용됩니다.
테이블 B
의 데이터는 대부분 a_id
을 포함하지 않으므로 GROUP BY
이 없어도 반환되는 ID의 대부분이 다릅니다. 그룹화에서 추구하는 목표는 결과 집합에 항상 A
의 주어진 수의 항목이 포함되도록하는 것입니다.
"증분 DISTINCT
/GROUP BY
"을 수행 할 수있는 방법이 있습니까? 내 순진한 생각으로 Postgres가 결과 행을 생성하고 숫자가 LIMIT
에 도달 할 때까지 점진적으로 그룹화하는 것으로 충분합니다. 대부분의 경우 대부분의 경우 a_id
값이 다르기 때문에 거의 순간적이어야합니다. 데이터를 쿼리하는 데 여러 가지 방법을 시도했지만 지금까지는 안정적으로 작동하는 것을 찾지 못했습니다.
포스트그레스 버전 9.6이며, 데이터 스키마는 다음과 같이 당신이 완전한 ORDER BY
절에 인덱스가있는 경우 플래너는 전체 테이블을 정렬하지 않도록 할 수있는 기회를 가지고
Table "public.a"
Column | Type | Modifiers
--------+-------------------+------------------------------------------------
id | bigint | not null default nextval('a_id_seq'::regclass)
bar | character varying |
Indexes:
"a_pkey" PRIMARY KEY, btree (id)
"ix_a_bar" btree (bar)
Referenced by:
TABLE "b" CONSTRAINT "b_a_id_fkey" FOREIGN KEY (a_id) REFERENCES a(id)
Table "public.b"
Column | Type | Modifiers
------------+-----------------------------+--------------------------------------------------
id | bigint | not null default nextval('b_id_seq'::regclass)
foo | character varying |
a_id | bigint | not null
created_at | timestamp without time zone |
Indexes:
"b_pkey" PRIMARY KEY, btree (id)
"ix_b_created_at" btree (created_at)
"ix_b_foo" btree (foo)
Foreign-key constraints:
"b_a_id_fkey" FOREIGN KEY (a_id) REFERENCES a(id)
약식 스키마와 샘플 데이터를 포함하십시오. 또한 이러한 세부 사항이 중요하므로 전체 쿼리를 표시하십시오. –
'distinct'는 *** 함수가 아닙니다 ***. 'distinct (id) '를 쓰는 것은 말이되지 않습니다. –
[postgresql-performance] (http://stackoverflow.com/tags/postgresql-performance/info)를 읽고 ** [edit] ** 귀하의 질문과 누락 된 정보를 제공하십시오. –