【问题标题】:Optimize Postgis Query and understanding performance优化 Postgis 查询和理解性能
【发布时间】:2017-11-12 21:24:22
【问题描述】:

我在 Digital Ocean Server 上有一个数据库,它对我来说似乎有点慢(有时超过一秒)。带有 postgis 的 Postgresql 正在那里运行。

这里有一些关于数据库房屋的统计数据,实际上只是存储了一些公寓:


房屋:190000

SELECT count(*) from houses;

过去 24 小时在线的房屋数:58000

SELECT count(*) FROM houses 
JOIN (select max(last_seen) as last_ts from houses) as dt 
ON last_seen >= dt.last_ts - interval '24 hour';

位于特定区域且活跃的房屋:3086

 select count(*) from houses 
 where ST_DWithin(geom, ST_MakePoint(52.5277411, 13.4)::geography,30000)
                 (active IS NULL OR active = TRUE)

这是实际的 SQL 查询,它有点慢。慢意味着一个查询有时需要超过一秒钟:

SELECT
      *,
      ST_DistanceSphere(geom, ST_MakePoint(52.5277411, 13.4)) as distace
      FROM houses 
      JOIN (select max(last_seen) as last_ts from houses) as dt 
      ON last_seen >= dt.last_ts - interval '24 hour'
      WHERE  
        ST_DWithin(geom, ST_MakePoint(52.5277411, 13.4)::geography,30000)
        AND (active IS NULL OR active = TRUE)

到目前为止我已经尝试过。删除连接,因为它有点多余。引入指数。

这里是查询说明:

知道如何改进吗?非常感谢!

PS:如果缺少某些数据,请告诉我,我会提供。

这里与解释分析相同:

数据库索引:

【问题讨论】:

  • 0) 计划看起来并不那个 糟糕... 1) 在你的问题中添加 DDL 2) 你有关于 geom 的空间索引吗? 3) EXPLAIN ANALYZE 而不是 EXPLAIN
  • 您好,是的,geom 上有一个空间索引。我将索引以及带有 EXPLAIN ANLYZE 的查询附加到问题中。非常感谢您的关注。
  • 顺便说一句:在大多数情况下,将布尔列定义为 NULLable:AND (active IS NULL OR active = TRUE) 没有什么意义(您可以在这里考虑条件索引)
  • 很高兴知道,我明白了。老实说,我对 Indices 不是很熟悉,但我认为这不是查询的瓶颈。
  • 4) 您的行大小相当大。

标签: sql postgresql performance geocoding postgis


【解决方案1】:

由于很多人试图提供帮助并给出了非常好的建议,我想发布我的最终解决方案: 正如 cmets 中提到的,您应该始终测量、优化、重复。表大小和索引是关键点。

由于我不是该主题的专家,因此可视化对 http://tatiyants.com 帮助很大

 Explain (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)
 select
  *,
  ST_DistanceSphere(geom, ST_MakePoint(52.5277411, 13.4)) as distace
  FROM houses
  JOIN (select max(last_seen) as last_ts from houses) as dt
  ON last_seen >= dt.last_ts - interval '24 hour'
  WHERE
    ST_DWithin(geom, ST_MakePoint(52.5277411, 13.4)::geography,30000)
    AND (active IS NULL OR active = TRUE);

query visualisation

这有助于基本理解。由于我已经在使用索引,所以没有那么多优化可能。就我而言,可以得到一些延迟的结果。我介绍了存储部分查询的物化视图:

CREATE MATERIALIZED VIEW mathouses
 select
  *,
  FROM houses
  JOIN (select max(last_seen) as last_ts from houses) as dt
  ON last_seen >= dt.last_ts - interval '24 hour'
  WHERE (active IS NULL OR active = TRUE);

然后在该视图上添加一个索引。并添加了一个由 cron 每小时调用的简单 shell 脚本:

#!/bin/sh
sudo -u <myuser>-Hi -- psql -d <db> -c 'refresh materialized view mathouses;'

我的最终结果:

 Explain (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)
 select
  *,
  ST_DistanceSphere(geom, ST_MakePoint(52.5277411, 13.4)) as distace
  FROM mathouses
  WHERE ST_DWithin(geom, ST_MakePoint(52.5277411, 13.4)::geography,30000);

query visualisation

对解决方案非常满意。现在它的速度是原来的 3 倍甚至更快。更进一步,下一个合乎逻辑的步骤是查看硬件或优化 postgresql 设置。

【讨论】:

    猜你喜欢
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 2021-12-06
    • 2016-12-01
    • 2020-07-05
    相关资源
    最近更新 更多