什么时候不应该使用空间索引?


29

我之所以这样问是因为我主要在Oracle上工作,但是在过去的一年中,我一直在使用PostGIS和SQLServer 2008翻倍。如果空间索引不返回ORA-13226错误,Oracle的大多数空间功能将无法工作:

13226,00000,“没有空间索引将不支持接口” // *原因:几何表没有空间索引。// *操作:验证在空间运算符中引用的几何表是否具有空间索引。

对我来说,这很有意义。您运行空间查询=您必须具有空间索引。但是据我了解,PostGIS和SQL Serve都不需要这样做。PostGIS甚至似乎具有明确不使用空间索引的功能(_ *,例如_STContains)。

所以问题是-在任何情况下都不应该使用空间索引?不一定是“采用还是放弃”方法,即不会有任何区别,但是不使用空间索引会降低性能吗?对我而言,最后一句话在用语上是矛盾的,但是为什么PostGIS会提供这些功能呢?


3
如果要查看索引使PostGIS变慢的位置,请设置enable_seqscan = off。这将迫使PostgreSQL每次使用索引。比较它的速度。
肖恩

感谢您启动此线程。我一直在网上查找信息,试图弄清为什么我的组织(政府)不使用其oracle / sde要素类和表中的空间(甚至属性)索引。现在,我要向他们提出一些论据,所以不必不必费劲就可以等待查询解决自己了。
麦克,

Answers:


12

mapoholic,

一般来说,除非您要处理非常小的表,否则没有理由不进行空间索引而进行空间查询。尽管您将使用ST_,它不使用索引,但具有&&可索引的短路盒运算符。以_ST开头的功能并不旨在供最终用户使用。它们存在的原因是因为它们必须这样做。PostGIS空间索引使用SQL内联来强制使用索引-_ST通常由GEOS完成,而&&是可能重新排序的索引。因此,_ST实际上是一个实现工件。

因此,简而言之,它不是一项功能,因此可以在更严格的空间检查之前立即将索引操作重新排序为全部发生。


欢呼声LR1234567。我想这就是我想要的。
mapoholic 2011年

25

如果您的数据集被添加并经常更新,则导致重建索引的INSERT,DELETE和UPDATE语句可能会使数据库变慢。

对于批量插入,例如将整个OSM数据集加载到数据库中,删除索引然后再创建它们可能会更快。

如果忽略索引的效率更高(例如,表足够小,可以装入内存),则数据库查询处理器应自动执行此操作。

我希望允许在没有空间索引的情况下运行查询的主要原因是评估使用索引获得的性能收益,而不必删除它。

最后,如果您希望对查询和地图显示显示出巨大的性能提升,则可能需要延迟在系统开发的适当时机创建索引...


3
(+1)我在最后一句话中发现一点愤世嫉俗吗?:-)
whuber

一点都不; ;-)但是,删除/重新创建经过仔细调整的索引是“为什么X花费大量时间用于数据库更改”的有用答案?
geographika,

感谢geoca-我同意胡布尔的话!;-)我知道您将在批量加载时删除/禁用空间索引-或与此相关的所有索引,但是您无法想到为什么不使用空间索引就进行空间查询的原因?如果表足够小,则使用索引可能不会产生足够的公平性,但选择不使用索引?不知道,我想我只是对PostGIS非空间索引功能的存在感到困惑……
mapoholic 2011年

2
如果表足够小且适合内存,则使用索引需要随机磁盘访问,这比进行顺序扫描的开销更大。wiki.postgresql.org/wiki/…–
肖恩

2
@mapoholic -在_ST_Contains可以从当你不得不手动做你的数据的前置滤波器遗留,从判断old.nabble.com/...
geographika

10

我认为这是隐含的,但我不是,当我有一个非空间索引,我可以改用使用空间索引的查询。例如,我有2,113,450点跨越了美国,并加载到了表格中。如果我想提取阿拉斯加州内的所有点,则可以执行一个空间查询,该查询使用点几何上的GIST索引与阿拉斯加州的几何进行比较,或者,我可以使用点数据(也已建立索引)中的“ state_alpha”字段,以返回所有具有“ state_alpha” =“ AK”的点。

您会问:“其中的空间部分在哪里?” 好吧,如果我需要在收集Alaska_points之后对它们进行一些进一步的空间分析,则首先使用非空间查询来收集这些点的几何形状会更快。这也意味着对于真正的大数据集,您可以受益于添加查找字段(或表)。再一次,我知道这对于每个有领导能力的人来说都是显而易见的,我之所以只提到它,是因为我在过去遇到的问题是,全局数据集仅在空间上建立索引,并且通用查询是“一个国家内的所有特征”。通过添加索引的country_fips字段,我们获得了很多性能。

以下是EXPLAIN ANALYZE的一些结果证明了这一点。(注意:我试图通过使用BBOX查询来使空间查询尽可能高效。使用状态轮廓只会使其变慢。)

# explain analyze select count(*) from gnis_names where state_alpha = 'AK';
Aggregate  (cost=57359.45..57359.46 rows=1 width=0) (actual time=76.606.. 76.607 rows=1 loops=1)
<snip>
Total runtime: 76.676 ms

# explain analyze select count(*) from gnis_names where the_geom && GeomFromText('POLYGON((-179.14734 51.219862,-179.14734 71.3525606439998,179.77847 71.3525606439998,179.77847 51.219862,-179.14734 51.219862))',4326);
Aggregate  (cost=27699.86..27699.87 rows=1 width=0) (actual time=86.523..86.524 rows=1 loops=1)
<snip>
Total runtime: 86.584 ms 

非常感谢。当您说这话时,它似乎很明显,但我的第一个想法是运行空间查询,而不是仅基于属性。为此+1!
mapoholic 2011年

0

刚注意到这句话

对我来说,这很有意义。您运行空间查询=您必须具有空间索引

对我而言,这根本没有任何意义,我认为SQL Server和Postgis都可以做得更好,或者至少不会打扰您性能细节。实际上,SQL Server和Postgis有时甚至根本不使用空间索引(恢复为全表扫描)。

对于Oracle,必须创建索引,因此必须填充user_sdo_geom_metadata。

只是将其与字母数字索引进行比较,出于性能原因它们就在那儿,您的SQL语句应该使用它,也可以不使用它。

在Oracle数据库中,删除索引,您将获得大量错误和无法使用空间查询的应用程序,因此无法正常工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.