PostGIS中的空间索引(一)

本文介绍如下索引:

  1. GIST
  2. BRIN

索引使使用空间数据库处理大型数据集成为可能。 如果不建立索引,则对功能的任何搜索都需要对数据库中的每个记录进行“顺序扫描”。 索引通过将数据组织到可以快速遍历以查找特定记录的搜索树中来加快搜索速度。 PostgreSQL默认支持三种索引:B树索引,SP-GiST和GiST索引。

B树用于可沿一个轴排序的数据。 例如数字,字母,日期。 空间数据可以沿着空间填充曲线,Z阶曲线或希尔伯特曲线进行排序。 但是,这种表示方式不允许加快常见的操作。

GiST(通用搜索树)索引将数据分为“一侧的事物”,“重叠的事物”,“内部的事物”,并且可以用于包括GIS数据在内的各种数据类型。 PostGIS使用在GiST之上实现的R-Tree索引来索引GIS数据。

1. GiST 索引

GiST代表“通用搜索树”,是索引的一种通用形式。 除GIS索引外,GiST还用于加快对不适合常规B树索引的各种不规则数据结构(整数数组,光谱数据等)的搜索。

一旦GIS数据表超过几千行,您将希望建立一个索引来加快数据的空间搜索(除非所有搜索都基于属性,在这种情况下,您将希望在数据库上建立普通索引)。 属性字段)。

在“ geometry”列上构建GiST索引的语法如下:

CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometryfield] ); 

上面的语法将始终建立2D索引。 要获取几何类型的n维索引,可以使用以下语法创建一个:

CREATE INDEX [indexname] ON [tablename] USING GIST ([geometryfield] gist_geometry_ops_nd);

建立空间索引是一项需要大量计算的工作。 它还会在创建表时阻止对表的写访问,因此,在生产系统上,以较慢的“并发感知”方式进行:

CREATE INDEX CONCURRENTLY [indexname] ON [tablename] USING GIST ( [geometryfield] ); 

构建索引后,有时强制PostgreSQL收集表统计信息(用于优化查询计划)会有所帮助:

VACUUM ANALYZE [table_name] [(column_name)];

2. BRIN 索引

BRIN代表“块范围索引”,是PostgreSQL 9.5中引入的一种通用索引形式。 BRIN是一种有损索引,它的主要用法是在读写性能上提供折衷。它的主要目标是处理非常大的表,其中一些列与其在表中的物理位置具有某些自然相关性。除了GIS索引之外,BRIN还用于加快对各种常规或不规则数据结构(整数,数组等)的搜索。

一旦GIS数据表超过几千行,您将希望建立一个索引来加快数据的空间搜索(除非所有搜索都基于属性,在这种情况下,您将希望在数据库上建立普通索引)。属性字段)。只要它们的大小不超过可用于数据库的RAM数量,并且只要您能够负担得起存储大小和写入工作量的损失,GiST索引就可以真正发挥作用。否则,可以将BRIN指数视为替代方案。

BRIN索引的想法是仅存储将所有表行中包含的所有几何包含在一组表块(称为范围)中的绑定框。显然,这种索引方法只有在以物理方式对数据进行排序的情况下才有效,该方式使得块范围的结果绑定框将互斥。所得的索引确实很小,但是在许多情况下,效率不如GiST索引。

建立BRIN索引的强度要比建立GiST索引的强度低。建立BRIN索引比GiST索引所需的时间少十倍是很常见的。由于BRIN索引只为一个或多个表块存储一个绑定框,因此这种索引消耗的磁盘空间最多少一千倍是很常见的。

您可以选择一个范围内要汇总的块数。如果减少此数字,索引将更大,但可能有助于获得更好的性能。

在“ geometry”列上建立BRIN索引的语法如下:

CREATE INDEX [indexname] ON [tablename] USING BRIN ( [geometryfield] ); 

上面的语法将始终建立2D索引。要获得3D维度索引,可以使用以下语法创建一个:

CREATE INDEX [indexname] ON [tablename] USING BRIN ([geometryfield] brin_geometry_inclusion_ops_3d);

还可以使用4D运算符类获得4D维度索引:

CREATE INDEX [indexname] ON [tablename] USING BRIN ([geometryfield] brin_geometry_inclusion_ops_4d);

以上这些语法将使用范围内的默认数字或块,即128。要指定要在一个范围内汇总的块数,可以使用此语法创建一个

CREATE INDEX [indexname] ON [tablename] USING BRIN ( [geometryfield] ) WITH (pages_per_range = [number]); 

另外,请记住,BRIN索引只会为大量的行存储一个索引值。如果您的表存储的几何尺寸混合在一起,则结果索引的性能可能很差。您可以通过选择存储的几何尺寸最少的运算符类别来避免这种性能下降

BRIN索引还支持“地理位置”数据类型。在“地理位置”列上建立BRIN索引的语法如下:

CREATE INDEX [indexname] ON [tablename] USING BRIN ( [geographyfield] ); 

上面的语法将始终为球体上的地理空间对象建立2D索引。

当前,这里仅考虑“包含支持”,这意味着对于&&,〜和@运算符可以用于2D情况(“geometry”和“geography”都可以),而&&&运算符可以用于3D情况。
目前不支持kNN搜索。

你可能感兴趣的:(GIS,Postgis,数据库,PostGIS,空间索引,GIS)