【问题标题】:ST_DistanceSphere very slow after Postgres/PostGIS upgradePostgres/PostGIS 升级后 ST_DistanceSphere 非常慢
【发布时间】:2023-01-17 23:54:13
【问题描述】:

多年来,我们一直在Compose 上成功使用 Postgres 9.6 和 PostGIS 2.4.1,但该服务正在关闭,因此我们正在尝试迁移到 Google Cloud 和 Cloud SQL。我们的 Cloud SQL 实例正在运行 Postgres 14 和 PostGIS 3.1.4。新数据库比旧数据库拥有更多的 CPU、磁盘和内存。

我们已经从 Postgres 9.6 (Compose) 中导出数据,如下所示:

pg_dump -h <ip> -U <username> -p <port> -d <database name> > data.sql

并将其像这样导入到 Postgres 14(在谷歌云上):

psql -U <username> -h <ip> --set ON_ERROR_STOP=on -f data.sql

这没有任何错误。

问题是,当我们以大约 5/s 的速度并行运行如下查询时,它在 Postgres 14/PostGIS 3.1 (Google Cloud) 上真的很慢:

SELECT ST_DistanceSphere('SRID=4326;POINT(13.154672331767976 55.673222697684935)'::geometry, mt.geofence) AS distance
FROM my_table mt 
WHERE ST_DistanceSphere('SRID=4326;POINT(13.543852374474474 55.93984692695315)'::geometry, mt.geofence) <= 2000
ORDER BY distance;

my_table 中大约有 13100 行。在我们的旧数据库中,这样的查询大约需要 200-300 毫秒,但在我们的新数据库中最多可能需要 4 秒。

我们有一个这样定义的索引(在新旧数据库中):

CREATE INDEX geofence_index ON my_table USING GIST (geofence);

在 Postgres 9.6/PostGIS 2.4.1 上运行 explain (analyze, buffers, format text) 返回:

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN                                                                                                                                                                     |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Sort  (cost=6085.40..6096.24 rows=4338 width=8) (actual time=204.360..204.361 rows=1 loops=1)                                                                                  |
|   Sort Key: (_st_distance('0101000020E61000003C143D36314F2A40A8BD4E292CD64B40'::geography, geography(geofence), '0'::double precision, false))                                 |
|   Sort Method: quicksort  Memory: 25kB                                                                                                                                         |
|   Buffers: shared hit=1392                                                                                                                                                     |
|   ->  Seq Scan on my_table mt  (cost=0.00..5823.32 rows=4338 width=8) (actual time=95.714..204.330 rows=1 loops=1)                                                         |
|         Filter: (_st_distance('0101000020E61000008B7084D173162B40444173E74CF84B40'::geography, geography(geofence), '0'::double precision, false) <= '2000'::double precision) |
|         Rows Removed by Filter: 13033                                                                                                                                          |
|         Buffers: shared hit=1389                                                                                                                                               |
| Planning time: 0.626 ms                                                                                                                                                        |
| Execution time: 204.404 ms                                                                                                                                                     |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
EXPLAIN 10
Time: 0.261s

在 Postgres 14/PostGIS 3.1.4 上运行 explain (analyze, buffers, format text) 返回:

+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN                                                                                                                                                   |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Gather Merge  (cost=257890.05..258183.87 rows=2555 width=8) (actual time=1893.020..1919.665 rows=1 loops=1)                                                  |
|   Workers Planned: 1                                                                                                                                         |
|   Workers Launched: 1                                                                                                                                        |
|   Buffers: shared hit=1591                                                                                                                                   |
|   ->  Sort  (cost=256890.04..256896.42 rows=2555 width=8) (actual time=1834.941..1834.943 rows=0 loops=2)                                                    |
|         Sort Key: (st_distance('0101000020E61000003C143D36314F2A40A8BD4E292CD64B40'::geography, geography(geofence), false))                                 |
|         Sort Method: quicksort  Memory: 25kB                                                                                                                 |
|         Buffers: shared hit=1591                                                                                                                             |
|         Worker 0:  Sort Method: quicksort  Memory: 25kB                                                                                                      |
|         ->  Parallel Seq Scan on my_table mt  (cost=0.00..256745.43 rows=2555 width=8) (actual time=1290.257..1834.816 rows=0 loops=2)                   |
|               Filter: (st_distance('0101000020E61000008B7084D173162B40444173E74CF84B40'::geography, geography(geofence), false) <= '2000'::double precision) |
|               Rows Removed by Filter: 6516                                                                                                                   |
|               Buffers: shared hit=1533                                                                                                                       |
| Planning Time: 0.212 ms                                                                                                                                      |
| Execution Time: 1919.704 ms                                                                                                                                  |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
EXPLAIN 15
Time: 2.055s (2 seconds), executed in: 2.053s (2 seconds)

FWIW 如果有一些数据需要升级,我们已经尝试在新数据库中运行SELECT postgis_extensions_upgrade();(两次),但这对查询性能没有影响。

什么可能导致 Postgres 14/PostGIS 3.1.4 中的查询变慢,如何解决?

【问题讨论】:

    标签: postgresql postgis


    【解决方案1】:

    track_io_timing 设置为 on,以便您的 EXPLAIN (ANALYZE, BUFFERS) 输出显示 I/O 时间。估计是磁盘慢了,不过还是确定一下比较好。

    【讨论】:

      猜你喜欢
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-19
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      相关资源
      最近更新 更多