PostgreSQL列索引查询优化问题
如果我在纬度* 69和经度* 46上创建索引,以下查询是否可以优化?PostgreSQL列索引查询优化问题
select * from locations where abs(latitude*69 - 3036) <= 25
and abs(longitude*46 - 8970) <= 25
或者我必须删除abs()
和代码它更像是:
select * from locations where (latitude*69 - 3036) between -25 and 25
and (longitude*46 - 8970) between -25 and 25
或甚至更简单:
select * from locations where latitude*69 between 3036-25 and 3036+25
and longitude*46 between 8970-25 and 8970+25
要查看查询是否可以通过索引进行优化,最简单的方法是做什么。
在查询之前创建一个GIST INDEX并使用EXPLAIN或EXPLAIN VERBOSE查看postgres使用的执行计划。如果您看到类似扫描SEQ,则不是使用索引。如果您看到索引扫描,则是使用该特定查询的索引。
为了使用GIS数据上的索引,必须使用使用geom/geog的边界框的函数。 Postgis中的函数使用边界框来使用索引,如所有的operators,或者一些使用内部运算符进行过滤的函数。
我认为你可以做出最好的查询,看看是否lonlat是在一个盒子里(就是你正在尝试做的?)是这样的:
SELECT *
FROM locations
WHERE
ST_Dwithin(
'POINT('||(longitude*46)||' '||(latitude*69)||')'::geometry,
'POINT(8970 3036)'::geometry
)
(未测试,但应该工作也与索引)
我从你的问题,你正在寻找的意义找到某个点周围25个单位框内的点。只要locations
只是点,任何postgres索引(GIN,GiST,b-tree,r-tree等)都可以在此查询上正常工作。如果位置包含其他几何形状(手机信号塔接收的形状,交付路线区域等),那么您需要一个GiST r-tree。但总体而言,更好的方法是,因为我从其他一些地理问题的印象中获得了地理位置对于您所从事的工作至关重要的问题,因此可以使用PostGIS或至少geometry support built into Postgres。你的榜样的直译应该是:
select * from locations
where my_point_column <@ box '((194.4, 43.36),(194.5 43.6))'
反对用几何类型列的Postgres
,和PostGIS的版本是多了很多的改进和公用事业的各种数据相同。
点,你的意思是整数?我试图把距离缩小到25英里(这比整个度还要小),因此分数是度数。如果通过点数来表示离散位置(地球平面上的一个点)与地区(例如城市或州)之间的距离,那么您正确使用两点之间的距离。我不想承担计算最精确距离的处理开销,所以我使用低开销的替代方法在我的位置周围的x英里方框(不是圆圈)内查找数据库中的所有点。 –
一个点只是2或3维记录,如笛卡尔平面中的(1,1),它距(0,0)为1.414。它不一定是一个整数,(1.414,1)。414)距离(0,0)为2。 Postgres支持这些几何形状(请参阅链接)以及它们的索引。简单的例子:假设你有点1 - >(123.4,56.7),2 - >(123.4,67.8)和3 - >(123.4,65.4)。通过在x,y坐标中交错10的幂来索引:3-> 10263544 1-> 10253647 2-> 10263748。看看最近的点是如何相邻的?现在你有一个1维问题!对经度分别编制索引... – unmounted
...和纬度将有所帮助,但它不会为您带来这些效率。另请参阅:http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves了解更多背景。 – unmounted
为什么你不只是创建索引和测试它? – splash
什么,并做一些实际的工作? ;)我可以做你正在问的东西,但如果它没有优化它,那么我不知道如何改变它,以便优化。我无法在Postgres网站上找到任何讨论什么是和不可优化的文档 - 您能为此推荐任何资源吗? –