加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – ST_DWithin不使用带非文字参数的索引

发布时间:2020-12-13 18:10:05 所属栏目:百科 来源:网络整理
导读:我在Amazon RDS上使用PostreSQL 9.3 w / PostGIS 2.1.8.我有一个名为project_location的表,它定义了“geo-fences”(每个都基本上是一个坐标和半径).使用名为“location”的几何列和名为“radius”的双列存储地理围栏.我在location列上有一个空间索引. CREATE
我在Amazon RDS上使用PostreSQL 9.3 w / PostGIS 2.1.8.我有一个名为project_location的表,它定义了“geo-fences”(每个都基本上是一个坐标和半径).使用名为“location”的几何列和名为“radius”的双列存储地理围栏.我在location列上有一个空间索引.
CREATE TABLE project_location
(
  ...
  location geography(Point,4326),radius double precision NOT NULL,...
)
CREATE INDEX gix_project_location_location 
ON project_location USING gist (location);

该表目前有大约50,000条记录.如果我查询表以查找geo-fence包含一个点的所有project_locations,就像

SELECT COUNT(*) 
FROM project_location 
WHERE ST_DWithin(location,ST_SetSRID(ST_MakePoint(-84.1000,34.0000),4326)::geography,radius);

我发现没有使用空间索引. EXPLAIN的结果显示如下:

"Aggregate  (cost=11651.97..11651.98 rows=1 width=0)"
"  ->  Seq Scan on project_location  (cost=0.00..11651.97 rows=1 width=0)"
"        Filter: ((location && _st_expand('0101000020E610000066666666660655C00000000000004140'::geography,radius)) AND ('0101000020E610000066666666660655C00000000000004140'::geography && _st_expand(location,radius)) AND _st_dwithin(location,'0101000020E610000066666666660655C00000000000004140'::geography,radius,true))"

但是,如果半径是一个常数值,如下所示

SELECT COUNT(*) 
FROM project_location 
WHERE ST_DWithin(location,1000);

空间索引用于EXPLAIN显示

"Aggregate  (cost=8.55..8.56 rows=1 width=0)"
"  ->  Index Scan using gix_project_location_location on project_location  (cost=0.28..8.55 rows=1 width=0)"
"        Index Cond: (location && '0101000020E610000066666666660655C00000000000004140'::geography)"
"        Filter: (('0101000020E610000066666666660655C00000000000004140'::geography && _st_expand(location,1000::double precision)) AND _st_dwithin(location,1000::double precision,true))"

在阅读了ST_DWithin如何使用索引后,我理解为什么会这样.基本上,基于半径的边界框用于“预过滤”候选点以在对这些点进行相对昂贵的距离计算之前确定可能的匹配.

我的问题是有没有办法进行这种类型的搜索,以便可以使用空间索引?基本上是一种用一堆可变半径地理围栏来查询表的方法吗?

PostGIS允许使用功能索引加快查询速度.我不确定如何在地理数据类型中执行此操作,因为那里没有ST_Expand,但如果将数据存储在某些Mercator投影中(例如,SRID = 3857),查询将非常简单.

理念:

>生成一个由您的点周围的半径单位扩展的框;
>在这些盒子上建立一个索引;
>根据这些框查询用户点;
>按精确半径重新检查.

在project_location表上:

create index on project_location using gist (ST_Expand(location,radius));

现在,您可以使用ST_Expand(位置,半径),就好像它是您的索引几何列一样.

select count(*) from project_location where ST_Intersects(ST_Expand(location,radius),<your_point>) and ST_Distance(location,<your_point>) < radius;

现在您正在跳过ST_DWithin,因为您希望重新检查从不尝试使用索引,并在几何函数上使用索引.

对于地理位置,您可以尝试使用ST_Envelope(ST_Buffer(geom,radius))将ST_Expand存根.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读