【问题标题】:Select query runs slow选择查询运行缓慢
【发布时间】: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_gistm_bue_geom_gistid5_index_index 的索引定义(CREATE INDEX ..)。从混淆的表名和列名中很难分辨,但c 上的类似索引可能会有所帮助

标签: postgresql select insert postgis


【解决方案1】:

看起来您正在进行大量计算,然后根据这些计算,您正在寻找基于参数的最小计算

很多这些计算都可以预先执行并存储在表格中。那么查询只是一个过滤器(我希望很容易在条件上建立索引。)

如果我们查看以下字段

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)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    • 2011-04-27
    相关资源
    最近更新 更多