【发布时间】:2021-08-01 02:39:37
【问题描述】:
我不是 Postgres/GIS 主题的专家,我对大型几何数据库(超过 2000 万条记录)有疑问。首先我的设置是这样的:
mmt=# select version();
-[ RECORD 1 ]-------------------------------------------------------------------------------------------------------------
version | PostgreSQL 13.2 (Debian 13.2-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
mmt=# select PostGIS_Version();
-[ RECORD 1 ]---+--------------------------------------
postgis_version | 3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
我正在查询的表包含以下列:
mmt=# \d titles
Table "public.titles"
Column | Type | Collation | Nullable | Default
----------------------+--------------------------+-----------+----------+-----------------------------------------
ogc_fid | integer | | not null | nextval('titles_ogc_fid_seq'::regclass)
wkb_geometry | bytea | | |
timestamp | timestamp with time zone | | |
end | timestamp with time zone | | |
gml_id | character varying | | |
validfrom | character varying | | |
beginlifespanversion | character varying | | |
geom_bounding_box | geometry(Geometry,4326) | | |
Indexes:
"titles_pkey" PRIMARY KEY, btree (ogc_fid)
"geom_idx" gist (geom_bounding_box)
geom_bounding_box 列包含 wkb_geometry 的边界框。我创建了该边界框列,因为 wkb 几何超出了 GIST 索引中项目的默认大小限制。其中一些是相当复杂的几何图形,由几十个点组成一个多边形。相反,使用边界框意味着我可以在该列上放置一个索引作为加快搜索速度的一种方式。至少理论上是这样。
我的搜索旨在查找位于给定点 100 米范围内的几何图形,如下所示,但这需要两分钟多的时间才能返回。我想在一秒钟内完成!:
select ogc_fid, web_geometry from titles where ST_DWithin(geom_bounding_box, 'SRID=4326;POINT(-0.145872 51.509691)'::geography, 100);
下面是一个基本的解释输出。我能做些什么来加快这件事的速度?
谢谢!
mmt=# explain select ogc_fid from titles where ST_DWithin(geom_bounding_box, 'SRID=4326;POINT(-0.145872 51.509691)'::geography, 100);
-[ RECORD 1 ]----------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Gather (cost=1000.00..243806855.33 rows=2307 width=4)
-[ RECORD 2 ]----------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Workers Planned: 2
-[ RECORD 3 ]----------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | -> Parallel Seq Scan on titles (cost=0.00..243805624.63 rows=961 width=4)
-[ RECORD 4 ]----------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Filter: st_dwithin((geom_bounding_box)::geography, '0101000020E61000006878B306EFABC2BF6308008E3DC14940'::geography, '100'::double precision, true)
-[ RECORD 5 ]----------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | JIT:
-[ RECORD 6 ]----------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Functions: 4
-[ RECORD 7 ]----------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Options: Inlining true, Optimization true, Expressions true, Deforming true
【问题讨论】:
-
“几十个点”对于 PostGIS 来说并不大也不复杂——我只是简单地索引几何列,PostGIS 会自动使用边界框。
-
@IanTurton mmt=# 使用 gist(wkb_geometry) 在标题上创建索引 geometry_idx;错误:索引行需要 16368 字节,最大大小为 8191 因此需要压缩这些几何记录的大小,这就是边界框的用途。看来,仅索引无法处理对象大小。
-
那是哪个版本的 PostGIS?我从未见过比这更大的几何形状的问题。
-
@IanTurton - mmt=# select PostGIS_Version(); postgis_version --------------------------------------- 3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
-
尝试使用 spgist 代替 gist?
标签: postgresql indexing geospatial postgis spatial-index