
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存根.
总结以上是内存溢出为你收集整理的postgresql – ST_DWithin不使用带非文字参数的索引全部内容,希望文章能够帮你解决postgresql – ST_DWithin不使用带非文字参数的索引所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)