[SQL] 왜 다음은 크게 쿼리 시간을 증가에 가입합니까?
SQL왜 다음은 크게 쿼리 시간을 증가에 가입합니까?
여기 스타 스키마를하고 난 사실 테이블을 조회하고 하나의 아주 작은 차원 테이블에 가입하고 싶습니다. 정말 다음을 설명 할 수 없다 :
EXPLAIN ANALYZE SELECT
COUNT(impression_id), imp.os_id
FROM bi.impressions imp
GROUP BY imp.os_id;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=868719.08..868719.24 rows=16 width=10) (actual time=12559.462..12559.466 rows=26 loops=1)
-> Seq Scan on impressions imp (cost=0.00..690306.72 rows=35682472 width=10) (actual time=0.009..3030.093 rows=35682474 loops=1)
Total runtime: 12559.523 ms
(3 rows)
내가 "해결"의미있는에 imp.os_id를 추가 할 수 있도록이 ~ 12600ms이 필요하지만 물론 어떤이 가입되어 데이터, 그래서 가입 :
EXPLAIN ANALYZE SELECT
COUNT(impression_id), imp.os_id, os.os_desc
FROM bi.impressions imp, bi.os_desc os
WHERE imp.os_id=os.os_id
GROUP BY imp.os_id, os.os_desc;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=1448560.83..1448564.99 rows=416 width=22) (actual time=25565.124..25565.127 rows=26 loops=1)
-> Hash Join (cost=1.58..1180942.29 rows=35682472 width=22) (actual time=0.046..15157.684 rows=35682474 loops=1)
Hash Cond: (imp.os_id = os.os_id)
-> Seq Scan on impressions imp (cost=0.00..690306.72 rows=35682472 width=10) (actual time=0.007..3705.647 rows=35682474 loops=1)
-> Hash (cost=1.26..1.26 rows=26 width=14) (actual time=0.028..0.028 rows=26 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 2kB
-> Seq Scan on os_desc os (cost=0.00..1.26 rows=26 width=14) (actual time=0.003..0.010 rows=26 loops=1)
Total runtime: 25565.199 ms
(8 rows)
이것은 효과적으로 내 쿼리의 실행 시간을 두 배로. 내 질문은 내가 사진에서 무엇을 떠나지 않았다입니까? 나는 그런 작은 검색 쿼리 실행 시간에 큰 차이를 일으키는 원인이되지 않았다 생각합니다.
해결법
-
==============================
1.(권장) 명시 적 ANSI 구문 가입으로 재 작성 :
(권장) 명시 적 ANSI 구문 가입으로 재 작성 :
SELECT COUNT(impression_id), imp.os_id, os.os_desc FROM bi.impressions imp JOIN bi.os_desc os ON os.os_id = imp.os_id GROUP BY imp.os_id, os.os_desc;
더 많거나 적은 하나 정확히 이상 일치하는 노출의 모든 행에 대해 os_desc에서 발견되면 우선, 두 번째 쿼리는 잘못 될 수 있습니다. 이것은 당신이 장소에 os_id에 외래 키 제약 조건이있는 경우, 배제 보장하는 참조 무결성, 플러스 NOT NULL 제약 bi.impressions.os_id에 할 수 있습니다. 그렇다면, 첫 번째 단계에서,에 단순화 :
SELECT COUNT(*) AS ct, imp.os_id, os.os_desc FROM bi.impressions imp JOIN bi.os_desc os USING (os_id) GROUP BY imp.os_id, os.os_desc;
계산 열이 NULL이 아닌 경우 (*) 빠른 카운트 (열) 여기에 상응하는보다. 그리고 카운트 열 별칭을 추가합니다.
빠른, 아직 :
SELECT os_id, os.os_desc, sub.ct FROM ( SELECT os_id, COUNT(*) AS ct FROM bi.impressions GROUP BY 1 ) sub JOIN bi.os_desc os USING (os_id)
집계 첫째, 나중에 가입 할 수 있습니다. 자세한 내용은 여기 :
-
==============================
2.
HashAggregate (cost=868719.08..868719.24 rows=16 width=10) HashAggregate (cost=1448560.83..1448564.99 rows=416 width=22)
흠, 10 내지 22의 폭이 두배이다. 아마 당신은 그룹화 대신 이전 한 후 가입해야합니까?
-
==============================
3.다음 쿼리는 쿼리 실행 시간을 증가시키지 않고 문제를 해결한다. 매우 간단한 조인을 추가로 크게 실행 시간이 증가하지 왜 질문은 여전히 유효하지만, 결국 답을 수있는 분야에서 폭 넓은 경험을 가진 포스트 그레스의 특정 질문과 사람이 될 수 있습니다.
다음 쿼리는 쿼리 실행 시간을 증가시키지 않고 문제를 해결한다. 매우 간단한 조인을 추가로 크게 실행 시간이 증가하지 왜 질문은 여전히 유효하지만, 결국 답을 수있는 분야에서 폭 넓은 경험을 가진 포스트 그레스의 특정 질문과 사람이 될 수 있습니다.
WITH OSES AS (SELECT os_id,os_desc from bi.os_desc) SELECT COUNT(impression_id) as imp_count, os_desc FROM bi.impressions imp, OSES os WHERE os.os_id=imp.os_id GROUP BY os_desc ORDER BY imp_count;
from https://stackoverflow.com/questions/18970357/why-does-the-following-join-increase-the-query-time-significantly by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 최대 열 값과 인덱스 값마다 하나 개의 행을 선택 (0) | 2020.06.19 |
---|---|
[SQL] 오라클의 외래 키 생성 문제 (0) | 2020.06.19 |
[SQL] 데이터베이스 내부에 저장된 모든 이미지를 표시하는 방법 (0) | 2020.06.19 |
[SQL] 왜 PostgreSQL는 작은 테이블에 내 인덱스를 사용하지 않는? (0) | 2020.06.19 |
[SQL] 어떻게 웹 브라우저에서 오디오 및 비디오 파일을 재생하려면? (0) | 2020.06.18 |