PostGIS教程十一:空间索引
目录
一、空间索引是怎样工作的?
二、纯索引查询
三、分析
四、清理(VACUUM)
五、相关函数
回想一下,空间索引是空间数据库的三个关键特性之一。空间索引使得使用空间数据库存储大型数据集成为可能。在没有空间索引的情况下,对要素的任何搜索都需要对数据库中的每条记录进行"顺序扫描"。索引通过将数据组织到搜索树中来加快搜索速度,搜索树可以快速遍历以查找特定记录。
空间索引是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和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;
五、相关函数
附录: PostGIS官方教程汇总目录
PostGIS教程十一:空间索引相关推荐
- 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩:纹理映射技术(二)...
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 作者:毛星云(浅墨) 邮箱: happylifemxy@163.com 本篇文章里,我们首先对Direct3D之中固定功能流水线中的 ...
- TypeScript系列教程十一《装饰器》 -- 属性装饰器
系列教程 TypeScript系列教程一<开篇> TypeScript系列教程二<安装起步> TypeScript系列教程三<基础类型> TypeScript系列教 ...
- 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩 纹理映射技术 二
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...
- PyQt5教程(十一)——实现QQ登录界面(五、实现密码框中的小键盘图标)
PyQt5教程(十一)--实现QQ登录界面(五.实现密码框中的小键盘图标) 上篇文件,我们添加了qss样式表,其中也添加了登录界面密码框中的小键盘按钮资源风格. PyQt5教程(十)--实现QQ登录界 ...
- PostGIS教程四:加载空间数据
在各种库和应用程序的支持下,PostGIS提供了许多用于加载数据的选项. 本节将重点介绍使用PostGIS shapefile加载工具加载shapefile的基础知识. 一.PostGIS shape ...
- PostGIS教程五:数据
目录 一.nyc_census_blocks 二.nyc_neighborhoods 三.nyc_streets 四.nyc_subway_stations 五.nyc_census_sociodat ...
- PostGIS教程十三:地理
目录 一.使用Geography 二.创建一个Geography表 三.转换为Geometry 四.为什么使用Geography 坐标为"地理(geographics)"或者说是& ...
- 【STM32】HAL库 STM32CubeMX教程十一---DMA (串口DMA发送接收)
前言: 本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1.芯片: STM32F407ZET6/ STM32F103ZET6 ...
- NVisionXR_iOS教程十一 —— 多场景切换
本章节教大家如何两个场景进行来回切换. 打开上一章节的代码, 1.将MyFirstScene的注释打开 2.将VideoScene的启动状态改为GENERAL_SCENEPLAY,代码如图 ...
最新文章
- 拒绝赛博朋克:斯坦福HAI报告警示“科技巨头垄断AI研究已成威胁”,力挺「国家安全云」计划...
- Spark常规性能调优三:并行度调节
- 傅里叶级数的数学推导
- Python中MySQLdb的各种常见用法
- k邻近算法(KNN)实例
- python函数测试_Python测试函数的方法之一
- java设置绝对布局_浅谈Java绝对布局 原创
- crontab——Linux 下的定时任务
- Unreal Engine 4 —— 基于Kajiya-Kay的材质迭代
- 系统重温Pandas笔记:(六)连接
- 颜色RGB 与 html 代码 对照表
- 零基础学python这本书怎么样-怎样学 Python?
- AUTOSAR-Fee模块
- CorelDRAW X8窗口提示非法软件禁用解决方法最新教程分享
- 微信小程序开发笔记1——使用npm脚本实现自动化切换环境配置
- 【前端】用javaScript实现实现一个球池的效果
- CSS-7-美化网页元素
- python自动化赚钱-薅羊毛 | Python 自动化带你轻松赚钱(完结版)
- 【折腾】独立博客之「熵」
- 「超算」解决HPL配置时 libfabric.so.1不存在的问题
热门文章
- [画皮Ⅱ/画皮2][BD-RMVB.720p.国语中字][2012年最新奇幻]
- 北京市金融工作局:大数据重塑未来金融监管方式
- mysql phpwind_PHPWind环境搭建(Linux)
- 2017滴滴校招 数字和为sum的方法数(DP)
- 自己开发了一款视频播放器app
- WES分析7-VCF
- Google Earth Engine——可视化的美国加州圣华金河流域的100年气候预测模型
- Win7电池电量设置
- javascript渐变色算法
- MIT四足机器人MIT Cheetah的硬件框架