아래 쿼리의 성능을 개선하려고합니다. 쿼리를 작성하는 방법 (FROM 절의 하위 쿼리, WHERE 절의 하위 쿼리)에 상관없이 postgres는 county = 24 인 60 개의 행만 있어도 고가의 ST_DWITHIN 함수를 통해 ~ 570K 행을 모두 실행해야합니다. postgis func을 통해 실행하기 전에 postgres가 county = 24를 필터링하도록하려면 어떻게해야합니까? 700ms는 너무 많은 우려의 원인은 아니지만이 표가 10M +로 증가함에 따라 성능이 걱정됩니다.
또한 p.id는 기본 키이고, p.zipcode는 fk 인덱스이고, z.county는 fk 인덱스이며, p.geom에는 GiST 인덱스가 있습니다.
질문:
EXPLAIN ANALYZE
SELECT count(p.id)
FROM point AS p
LEFT JOIN zipcode AS z
ON p.zipcode = z.zipcode
WHERE z.county = 24
AND ST_DWithin(
p.geom,
ST_SetSRID(ST_Point(-121.479756008715,38.563236291512),4269),
16090.0,
false
)
설명 분석 :
Aggregate (cost=250851.91..250851.92 rows=1 width=4) (actual time=724.007..724.007 rows=1 loops=1)
-> Hash Join (cost=152.05..250851.34 rows=228 width=4) (actual time=0.359..723.996 rows=51 loops=1)
Hash Cond: ((p.zipcode)::text = (z.zipcode)::text)
-> Seq Scan on point p (cost=0.00..250669.12 rows=7437 width=10) (actual time=0.258..723.867 rows=63 loops=1)
Filter: (((geom)::geography && '0101000020AD10000063DF8B52B45E5EC070FB752018484340'::geography) AND ('0101000020AD10000063DF8B52B45E5EC070FB752018484340'::geography && _st_expand((geom)::geography, 16090::double precision)) AND _st_dwithin((g (...)
Rows Removed by Filter: 557731
-> Hash (cost=151.38..151.38 rows=54 width=6) (actual time=0.095..0.095 rows=54 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 3kB
-> Bitmap Heap Scan on zipcode z (cost=4.70..151.38 rows=54 width=6) (actual time=0.023..0.079 rows=54 loops=1)
Recheck Cond: (county = 24)
Heap Blocks: exact=39
-> Bitmap Index Scan on fki_zipcode_county_foreign_key (cost=0.00..4.68 rows=54 width=0) (actual time=0.016..0.016 rows=54 loops=1)
Index Cond: (county = 24)
Planning time: 0.504 ms
Execution time: 724.064 ms
point
county = 24 인 ~ 60 행을 새 테이블에 모두 복사하면 쿼리가 724와 비교하여 .453ms 만 걸리므로 큰 차이가 있습니다.
count(*)
스타일 문제로 사용해야합니다 . id
당신이 말하는 것처럼 pkid 라면 , 그것은 NOT NULL
동일하다는 것을 의미합니다. count(id)
당신 id
이 nullable 경우 해당 질문을해야한다는 단점을 제외하고 .