PostGIS学习教程十:空间索引

PostGIS学习教程十:空间索引

回想一下,空间索引是空间数据库的三个关键特性之一。空间索引使得使用空间数据库存储大型数据集成为可能。在没有空间索引的情况下,对要素的任何搜索都需要对数据库中的每条记录进行"顺序扫描"。索引通过将数据组织到搜索树中来加快搜索速度,搜索树可以快速遍历以查找特定记录。

空间索引是PostGIS的最大价值之一。在前面的示例中,构建空间连接需要对整个表进行相互比较。这样做的代价很高:连接两个各包含10000条记录的表(每个表都没有索引)将需要进行100000000次比较;如果使用空间索引,则比较次数可能低至20000次。
加载nyc_census_blocks表时,pgShapeLoader会自动创建名为nyc_census_blocks_geom_idx的空间索引。

为了演示空间索引对性能有多重要,让我们在没有空间索引的情况下搜索nyc_census_blocks表。

我们的第一步是删除索引:

DROP INDEX nyc_census_blocks_geom_idx;

在这里插入图片描述
注意:DROP INDEX语句从数据库系统中删除现有索引。有关更多信息,请参见PostgreSQL文档。

现在,查看pgAdmin查询窗口右下角的"计时表"并运行以下命令。我们的查询将搜索每个单独的人口普查块(census block),以查找宽街(Broad Street)那个记录。

SELECT blocks.blkid
FROM nyc_census_blocks blocks
JOIN nyc_subway_stations subways
ON ST_Contains(blocks.geom, subways.geom)
WHERE subways.name = 'Broad St';

在这里插入图片描述
nyc_census_blocks表非常小(只有几千条记录),因此即时没有索引,查询也非常快。

现在,重新添加空间索引并再次进行查询:

CREATE INDEX nyc_census_blocks_geom_idx
ON nyc_census_blocks
USING GIST (geom);

注意:USING GIST子句告诉PostgreSQL在构建索引时使用generic index structure(GIST-通用索引结构)。创建索引时,如果收到类似错误:ERROR:index row requires 11340 bytes,maximum size is 8911,则可能是因为没有添加USING GIST子句。
在这里插入图片描述
在我的测试计算机上,时间下降到11毫秒。表越大,索引查询的相对速度提高就越大。

文章目录

  • PostGIS学习教程十:空间索引
  • 一、空间索引是怎样工作的?
    • 二、纯索引查询
  • 三、分析(ANALYZE)
  • 四、清理(VACUUM)
  • 五、相关函数


一、空间索引是怎样工作的?

标准数据库索引基于某个列的值创建层次结构树。空间索引略有不同-它们不能索引几何要素本身,而是索引几何要素的边界框。
在这里插入图片描述
在上图中,与黄星相交的线串数是一条,即红线。但是与黄色框相交的要素的边界框是两个,红框和蓝框。

空间数据库回答"哪些直线与黄星相交"这一问题使用的方法是,首先使用空间索引(速度非常快)判断"哪些框与黄色框相交",然后仅对第一次返回的几何要素进行"哪些直线与黄星相交"的精确计算。

对于一个大的数据表来说,这种先计算出近似结果,然后进行精确测试的"两遍"机制可以从根本上减少计算量。(这种思想就是粗调和精调的思想,就像显微镜一样有粗粒度的调整和细粒度的调整。很多事物都涉及到这个思想,它的作用就是减少了耗费的代价)

PostGIS和Oracle Spatial都具有相同的"R-Tree"空间索引结构。R-Tree将数据分解为矩形(rectangle)、子矩形(sub-rectangle)和子-子矩形(sub-sub rectangle)等。它是一种可自动处理可变数据的密度和对象大小的自调优(self-tuning)索引结构。
在这里插入图片描述

二、纯索引查询

PostGIS中最常用的函数(ST_Contains、ST_Intersects、ST_DWithin等)都包含自动索引过滤器。但有些函数(如ST_Relate)不包括索引过滤器。

要使用索引执行边界框搜索(即纯索引查询-Index only Query-没有过滤器),需要使用"&&“运算符。对于几何图形,&&运算符表示"边界框重叠或接触”(纯索引查询),就像对于数字,"=“运算符表示"值相同”。

让我们将对"West Village"社区人口的纯空间索引查询与更精确的查询进行比较。使用&&操作符的纯索引查询如下所示:

SELECT Sum(popn_total)
FROM nyc_neighborhoods neighborhoods
JOIN nyc_census_blocks blocks
ON neighborhoods.geom && blocks.geom
WHERE neighborhoods.name = 'West Village';

在这里插入图片描述
现在,让我们使用更精确的ST_Intersects函数执行相同的查询:

SELECT Sum(popn_total)
FROM nyc_neighborhoods neighborhoods
JOIN nyc_census_blocks blocks
ON ST_Intersects(neighborhoods.geom, blocks.geom)
WHERE neighborhoods.name = 'West Village';

在这里插入图片描述
结果数量低得多!第一个查询汇总与社区(neighborhood)关于边界框相交的每个人口统计块(census block);第二个查询仅汇总了与该社区几何图形本身严格相交的人口统计块。

三、分析(ANALYZE)

PostgreSQL查询规划器(query planner)智能地选择何时使用或不使用空间索引来计算查询。与直觉相反,执行空间索引搜索并不总是更快:如果搜索将返回表中的每条记录,则遍历索引树以获取每条记录实际上比从一开始线性读取整个表要慢(注意这句话)。

为了弄清楚要处理的数据的大概内容(读取表的一小部分信息,而不是读取表的大部分信息),PostgreSQL保存每个索引列中数据分布的统计信息。默认情况下,PostgreSQL定期收集统计信息。但是,如果你在短时间内更改了表的构成,则统计数据将不会是最新的。

为确保统计信息与表内容匹配,明智的做法是在表中加载和删除大容量数据后手动运行ANALYZE命令。这将强制统计系统收集所有索引列的统计信息。

ANALYZE命令要求PostgreSQL遍历该表并更新用于查询操作而估算的内部统计信息。

ANALYZE nyc_census_blocks;

四、清理(VACUUM)

值得强调的是,仅仅创建空间索引不足以让PostgreSQL有效地使用它。每当创建新索引或对表大量更新、插入或删除后,都必须执行清理(VACUUMing)。VACUUM命令要求PostgreSQL回收表页面中因记录的更新或删除而留下的任何未使用的空间。

清理对于数据库的高效运行非常关键,因此,PostgreSQL提供了一个“自动清理(autovacuum)"选项。

默认情况下,自动清理机制会根据活动级别确定的合理时间间隔自动清理(恢复空间)和分析(更新统计信息)。虽然这对于高度事务性的数据库是必不可少的功能,但在添加索引或大容量数据之后等待自动清理运行是不明智的,如果执行大批量更新,则应该手动运行VACUUM命令。

根据需要,可以单独执行清理和分析。发出VACUUM命令不会更新数据库统计信息;同样,执行ANALYZE命令也不会清理未使用的表空间。这两个命令都可以针对整个数据库、单个表或单个列运行。

VACUUM ANALYZE nyc_census_blocks;

五、相关函数

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/199880.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式——七大设计原则

设计模式——七大设计原则 1、单一职责原则(SRP)2、开放封闭原则(OCP)3、依赖倒转原则(DIP)4、里氏替换原则 (LSP)5、接口隔离原则 (ISP)6、合成/聚合复用原则 (CARP)7、迪米特法则 (LoD) 了解 设计模式 的…

网络编程HTTP协议进化史

一、Http报文格式 具有约定格式的数据块 请求报文 request 状态行:本次请求的请求方式(post get)资源路径url http 协议的版本号,中间用空格划分 本次请求的请求方式(post get)资源路径url http 协议…

如何使用llm 制作多模态

首先将任何非字符的序列信息使用特殊n个token 编码。 具体编码方法以图像为例子说明: 将固定尺寸图像如256256 的图像分割为1616 的子图像块。 将已知的所有图像数据都分割后进行str将其看做是一个长的字符,而后去重后方式一个词表。 使用特殊1024 个tok…

ajax检查密码是否一致

如果你只需要在前端展示密码是否匹配的信息而不涉及后端处理&#xff0c;可以通过纯HTML和JavaScript实现。以下是一个简单的例子&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"…

解决方案:Mac 安装 pip

python3 --version 通过以下命令来下载pip&#xff1a; curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py curl命令允许您指定一个直接下载链接。使用-o选项来设置下载文件的名称。 通过运行以下命令安装下载的包&#xff1a; python3 get-pip.py

【开源】基于JAVA的医院门诊预约挂号系统

项目编号&#xff1a; S 033 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S033&#xff0c;文末获取源码。} 项目编号&#xff1a;S033&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 功能性需求2.1.1 数据中心模块2.1.2…

Day02 Liunx高级程序设计2-文件IO

系统调用 概念 是操作系统提供给用户使其可以操作内核提供服务的一组函数接口 用户态和内核态 其中 ring 0 权限最高&#xff0c;可以使用所有 CPU 指令&#xff0c; ring 3 权限最低&#xff0c;仅能使用 常规 CPU 指令&#xff0c;这个级别的权限不能使用访问硬件资…

深度学习在图像识别中的应用

深度学习在图像识别中的应用 摘要&#xff1a;本文介绍了深度学习在图像识别领域的应用&#xff0c;包括卷积神经网络&#xff08;CNN&#xff09;的基本原理、常见模型以及在图像识别中的优势。并通过实验展示了深度学习在图像识别中的实际应用和效果。 一、引言 随着数字化…

react传值

在React中&#xff0c;父组件向子组件传递数据是通过props实现的&#xff0c;而子组件向父组件传递数据则需要通过回调函数的方式。对于爷孙组件之间的通信&#xff0c;可以通过在中间组件上设置props和回调函数来传递数据。兄弟组件之间的通信则需要通过共享状态或者通过父组件…

写给初学者的 HarmonyOS 教程 -- 状态管理(@State/@Prop/@Link 装饰器)

State 装饰的变量&#xff0c;或称为状态变量&#xff0c;一旦变量拥有了状态属性&#xff0c;就和自定义组件的渲染绑定起来。当状态改变时&#xff0c;UI 会发生对应的渲染改变&#xff08;类似 Compose 的 mutablestateof &#xff09;。 Prop 装饰的变量可以和父组件建立单…

深度学习在计算机视觉中的应用

深度学习在计算机视觉中的应用 摘要&#xff1a;本文介绍了深度学习在计算机视觉领域的应用&#xff0c;包括目标检测、图像分类、人脸识别等。通过分析深度学习在计算机视觉中的实际应用案例&#xff0c;阐述了深度学习在计算机视觉中的优势和未来发展趋势。 一、引言 计算…

学习SpringCloud

JWT JWT&#xff08;JSON Web Token&#xff09;是一种用于在网络应用间传递信息的安全标准。JwtTool生产成 三个部分组成&#xff1a;头部&#xff08;Header&#xff09;、载荷&#xff08;Payload&#xff09;和签名&#xff08;Signature&#xff09;。 工作流程如下&…

更新 Node.js 和 npm 使用 nvm

更新 Node.js 和 npm 使用 nvm 问题: 当前 Node.js 版本为 16.20.2&#xff0c;不兼容所需的 npm 版本 10.2.4。需要的 npm 版本 10.2.4 要求 Node.js 版本至少为 18.17.0 或更高。 解决步骤: 查看可用的 Node.js 版本 使用 nvm list available 命令来查看所有可安装的 Node…

【C++ protobuf中对不同消息内容进行赋值的方式】

本文中用到的消息结构&#xff1a; message PointNameInfo {optional double longitude 1;// 经度坐标optional double latitude 2;// 纬度坐标optional uint64 timestamp_sec 3;// 时间戳optional uint32 scale 4;optional string name 5; }message PointInfo {optional…

C++之vector插入初始化性能优化

C整理集合C刷题基础知识&#xff08;栈、队列、hash、STL、基础函数等&#xff09;---持续更新-CSDN博客 vector的高级使用&#xff08;优化&#xff09; 1、元素插入&#xff08;优化&#xff09; 对于vector的元素插入存在两个函数push_back()以及emplace_back()&#xff…

记录 | CUDA编程中用constexpr替代__host____device__

比如用 __host__ & __device__ 的情况如下&#xff1a; #include <cstdio> #include <cuda_runtime.h>__host__ __device__ void say_hello(){printf("Hello, world!\n"); }__global__ void kernel(){say_hello(); }int main(){kernel<<<1…

使用rust slint开发桌面应用

安装QT5&#xff0c;过程省略 安装rust&#xff0c;过程省略 创建工程 cargo new slint_demo 在cargo.toml添加依赖 [dependencies] slint "1.1.1" [build-dependencies] slint-build "1.1.1" 创建build.rs fn main() {slint_build::compile(&quo…

8.HTTP工作原理

HTTP是什么 HTTP工作原理 HTTP协议的请求类型和响应状态码 总结 1.HTTP是什么 HTTP超文本传输协议就是在一个网络中上传下载文件的一套规则 2.HTTP工作原理 HTTP超文本传输协议的本质是TCP通信&#xff0c;链接—>请求—>响应—>断开 3.HTTP协议的请求类型和响应状…

qt/c/c++文件操作总结

1. 读取文件 1.1 Qt以二进制方式读取大文件返回char* 在Qt中以二进制模式读取一个大文件(以500MB为例)并将其内容存储到char*数组中,需要谨慎处理内存分配。以下是实现这一功能的步骤和示例代码: 1. 打开文件 使用QFile类以二进制模式打开文件。 2. 检查文件大小 使用…

Java+Swing+Mysql实现超市管理系统

一、系统介绍 1.开发环境 操作系统&#xff1a;Win10 开发工具 &#xff1a;IDEA2018 JDK版本&#xff1a;jdk1.8 数据库&#xff1a;Mysql8.0 2.技术选型 JavaSwingMysql 3.功能模块 4.系统功能 1.系统登录登出 管理员可以登录、退出系统 2.商品信息管理 管理员可以对商品信息…