Tôi đang cố gắng cải thiện hiệu suất cho truy vấn bên dưới. Bất kể tôi viết truy vấn như thế nào (truy vấn con trong mệnh đề TỪ, truy vấn con trong mệnh đề WHERE) postgres khăng khăng chạy tất cả ~ 570K hàng thông qua hàm ST_DWITHIN đắt tiền mặc dù chỉ có 60 hàng trong đó quận = 24. Làm cách nào tôi có thể nhận được các postgres để lọc trên quận = 24 TRƯỚC KHI chạy qua func postgis mà dường như tôi sẽ nhanh hơn và hiệu quả hơn nhiều? 700ms không phải là nguyên nhân của quá nhiều mối quan tâm nhưng khi bảng này tăng lên 10 triệu + Tôi lo ngại về hiệu suất.
Cũng cần lưu ý, p.id là khóa chính, p.zipcode là chỉ mục fk, z.county là chỉ mục fk và p.geom có chỉ số GiST.
Truy vấn:
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
)
GIẢI THÍCH PHÂN TÍCH:
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
hàng trong đó quận = 24 vào một bảng mới, truy vấn chỉ mất 0,453ms so với 724 nên chắc chắn có sự khác biệt lớn.
count(*)
như một vấn đề của phong cách. Nếu id
là một pkid như bạn nói, điều NOT NULL
đó có nghĩa là chúng giống nhau. Ngoại trừ count(id)
có nhược điểm là bạn phải đặt câu hỏi đó nếu không id
có giá trị.