【发布时间】:2019-04-15 10:41:19
【问题描述】:
我有一个来自多个表的 postgres (postgis) 选择查询,我想插入到结果表中。问题是每次选择大约需要 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 和查询优化方面没有太多经验,所以我束手无策。你们认为我怎样才能使这个查询更快?
提前谢谢你。
【问题讨论】:
-
这看起来是一个 PostGIS 查询。考虑为 Postgres 的非常专业的扩展添加标签。
-
请edit 提出您的问题并包括
v_geom_gist、m_bue_geom_gist和id5_index_index的索引定义(CREATE INDEX ..)。从混淆的表名和列名中很难分辨,但c上的类似索引可能会有所帮助
标签: postgresql select insert postgis