我有一个postgres(postgis)select查询,该查询来自要插入结果表中的多个表。问题在于每个选择大约需要2秒钟,而且必须选择大约200万个选择,这使我的工作过程长达一个月。
问题是在同一脚本中,我有非常相似的Select查询,耗时0.3秒。结果表没有任何可能减慢其索引的索引,而其他选择查询使用相同的表,因此我不知道为什么这个表要花这么长时间。我已经对其进行了测试,并且无论它正在处理的行如何,它的运行速度都一样慢,因此这不是输入问题,而是查询本身,或者至少是我的猜测。
这是慢查询:
INSERT INTO result(a, b, c, d, e, f, g, Yutm, Xutm, Y, X, geom, distancia, v)
SELECT '{0}', m.b, r.nom_, c.id, l.tipo, d.distr, s.tipn, p.secc,
ST_Y(ST_TRANSFORM(p.geom,32613)),
ST_X(ST_TRANSFORM(p.geom,32613)),
ST_Y(ST_TRANSFORM(p.geom,4326)),
ST_X(ST_TRANSFORM(p.geom,4326)),
p.geom,
ST_DISTANCE(p.geom,v.geom), v.cat
FROM r, m, l, c, d, s, v, p
WHERE p.estado = '{0}'
AND left(m.b, 2) = '{0}'
AND p.id5 = '{1}'
AND ST_INTERSECTS(p.geom, m.geom)
AND ST_INTERSECTS(p.geom, l.geom)
AND ST_INTERSECTS(p.geom, c.geom)
AND ST_INTERSECTS(p.geom, d.geom)
AND ST_INTERSECTS(p.geom, s.geom)
AND ST_DWithin(p.geom, v.geom, 0.000524)
Order by p.id5, st_distance(p.geom,v.geom)
limit 1
这是该查询的解释:
Insert on result (cost=49452.92..49452.97 rows=1 width=334) (actual time=1804.548..1804.548 rows=0 loops=1)
-> Subquery Scan on "*SELECT*" (cost=49452.92..49452.97 rows=1 width=334) (actual time=1803.256..1803.257 rows=1 loops=1)
-> Limit (cost=49452.92..49452.92 rows=1 width=497) (actual time=1803.217..1803.217 rows=1 loops=1)
-> Sort (cost=49452.92..49454.20 rows=511 width=497) (actual time=1803.217..1803.217 rows=1 loops=1)
Sort Key: (st_distance(p.geom, v.geom))
Sort Method: top-N heapsort Memory: 25kB
-> Nested Loop (cost=15.37..49450.36 rows=511 width=497) (actual time=40.160..1803.105 rows=32 loops=1)
-> Nested Loop (cost=11.04..49211.22 rows=3 width=486) (actual time=39.800..1799.749 rows=32 loops=1)
Join Filter: ((p.geom && c.geom) AND _st_intersects(p.geom, c.geom))"
Rows Removed by Join Filter: 3222464
-> Nested Loop (cost=11.04..10687.66 rows=1 width=433) (actual time=5.510..326.752 rows=32 loops=1)
-> Nested Loop (cost=0.71..9623.19 rows=1 width=207) (actual time=5.450..324.692 rows=32 loops=1)
Join Filter: ((p.geom && l.geom) AND _st_intersects(p.geom, l.geom))
Rows Removed by Join Filter: 752544
-> Nested Loop (cost=0.71..129.53 rows=1 width=181) (actual time=0.269..5.447 rows=32 loops=1)
-> Nested Loop (cost=0.56..121.10 rows=1 width=162) (actual time=0.148..2.622 rows=32 loops=1)
Join Filter: ((p.geom && d.geom) AND _st_intersects(p.geom, d.geom))
Rows Removed by Join Filter: 64
-> Nested Loop (cost=0.56..94.63 rows=32 width=154) (actual time=0.018..0.074 rows=32 loops=1)
-> Index Scan using id5_index_index on p (cost=0.56..92.99 rows=1 width=122) (actual time=0.013..0.030 rows=1 loops=1)
Index Cond: (id5 = 10)
Filter: ((estado)::text = '01'::text)
Rows Removed by Filter: 30
-> Seq Scan on r (cost=0.00..1.32 rows=32 width=32) (actual time=0.004..0.014 rows=32 loops=1)
-> Materialize (cost=0.00..1.04 rows=3 width=40) (actual time=0.000..0.001 rows=3 loops=32)
-> Seq Scan on d (cost=0.00..1.03 rows=3 width=40) (actual time=0.001..0.003 rows=3 loops=1)
-> Index Scan using m_bue_geom_gist on m (cost=0.14..8.42 rows=1 width=14077) (actual time=0.085..0.086 rows=1 loops=32)
Index Cond: (p.geom && geom)
Filter: (("left((b)::text, 2) = '01'::text) AND _st_intersects(p.geom, geom))
Rows Removed by Filter: 1
-> Seq Scan on l (cost=0.00..3320.18 rows=23518 width=1007) (actual time=0.001..2.878 rows=23518 loops=32)
-> Bitmap Heap Scan on v (cost=10.33..1064.46 rows=1 width=226) (actual time=0.052..0.060 rows=1 loops=32)
Recheck Cond: (geom && st_expand(p.geom, '0.000524'::double precision))
Filter: ((p.geom && st_expand(geom, '0.000524'::double precision)) AND _st_dwithin(p.geom, geom, '0.000524'::double precision))
Rows Removed by Filter: 2
Heap Blocks: exact=64
-> Bitmap Index Scan on v_geom_gist (cost=0.00..10.33 rows=255 width=0) (actual time=0.042..0.042 rows=3 loops=32)
Index Cond: (geom && st_expand(p.geom, '0.000524'::double precision))
-> Seq Scan on c (cost=0.00..12089.03 rows=100703 width=762) (actual time=0.004..20.435 rows=100703 loops=32)
-> Bitmap Heap Scan on s (cost=4.33..33.70 rows=2 width=2046) (actual time=0.072..0.081 rows=1 loops=32)
Recheck Cond: (p.geom && geom)
Filter: _st_intersects(p.geom, geom)
Rows Removed by Filter: 2
Heap Blocks: exact=96
-> Bitmap Index Scan on s_geom_gist (cost=0.00..4.33 rows=7 width=0) (actual time=0.065..0.065 rows=3 loops=32)
Index Cond: (p.geom && geom)
Planning time: 6.801 ms
Execution time: 1804.740 ms
我在postgres和查询优化方面经验不足,因此束手无策。你们如何看待我可以使查询速度更快?
谢谢。
答案 0 :(得分:0)
您似乎进行了很多计算,然后根据这些计算来查找基于参数的最小计算
许多这些计算可以事先进行并存储在表格中。然后查询只是一个过滤器(我希望可以很容易地在条件上建立索引)。
因此,如果我们查看以下字段
ST_Y(ST_TRANSFORM(p.geom,32613)),
ST_X(ST_TRANSFORM(p.geom,32613)),
ST_Y(ST_TRANSFORM(p.geom,4326)),
ST_X(ST_TRANSFORM(p.geom,4326)),
ST_DISTANCE(p.geom,v.geom)
ST_INTERSECTS(p.geom, m.geom)
ST_INTERSECTS(p.geom, l.geom)
ST_INTERSECTS(p.geom, c.geom)
ST_INTERSECTS(p.geom, d.geom)
ST_INTERSECTS(p.geom, s.geom)
ST_DWithin(p.geom, v.geom, 0.000524)
st_distance(p.geom,v.geom)
如果使用这些值创建一个可以链接的新表或将其添加到现有表之一,则插入查询将更快。