选择查询运行缓慢

时间:2018-11-12 16:55:19

标签: postgresql select insert postgis

我有一个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和查询优化方面经验不足,因此束手无策。你们如何看待我可以使查询速度更快?

谢谢。

1 个答案:

答案 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)

如果使用这些值创建一个可以链接的新表或将其添加到现有表之一,则插入查询将更快。

相关问题