당신은 이것을 듣고 싶지 않을 수도 있지만, 속도를 높이는 가장 좋은 방법 SELECT DISTINCT
은 시작 하지 않는 DISTINCT
것입니다. 더 나은 데이터베이스 디자인이나 더 나은 쿼리로 많은 경우에 (전부는 아님) 피할 수 있습니다.
때로는 GROUP BY
다른 코드 경로가 필요하기 때문에 더 빠릅니다.
에서 특정 경우에 당신은 제거 할 수처럼, 그것은 보이지 않는다 DISTINCT
. 그러나 이런 종류의 쿼리가 많은 경우 특수 인덱스로 쿼리를 지원할 수 있습니다.
CREATE INDEX foo ON events (project_id, "time", user_id);
추가 user_id
는이 작업에서 인덱스 전용 스캔 을 얻는 경우에만 유용합니다 . 자세한 내용은 링크를 따르십시오. 쿼리 계획에서 값 비싼 비트 맵 힙 스캔 을 제거하면 쿼리 시간의 90 %가 소비됩니다.
귀하의 EXPLAIN
결과에 따르면 쿼리는 50 만 개의 일치하는 행 중 2,491 명의 개별 사용자를 압축해야한다고 알려줍니다. 이것은 당신이 무엇을하든 초고속이되지는 않지만 실질적으로 더 빠를 수 있습니다.
쿼리의 시간 간격이 항상 같으면 MATERIALIIZED VIEW
접는 user_id
시간 (project_id, <fixed time intervall>)
이 길어집니다. 그러나 시간 간격이 다양 할 가능성은 없습니다. 어쩌면 적어도 시간당 사용자 또는 다른 최소 시간 단위를 접을 수 있으며 상당한 오버 헤드를 보장하기에 충분한 성능을 구입할 수 있습니다.
Nitpick :
대부분의 술어는 다음과 "time"
같아야합니다.
AND "time" >= '2015-01-11 8:00:00'
AND "time" < '2015-02-10 8:00:00';
따로 : time
식별자로 사용하지 마십시오 . 표준 SQL 의 예약어 이며 Postgres의 기본 유형입니다.