如果我在纬度* 69和经度* 46上创建索引,那么下面的查询是否可以优化?
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
答案 0 :(得分:4)
要查看查询是否可以使用索引进行优化,最简单的方法就是执行splash所说的内容。
创建GIST INDEX并在查询之前使用EXPLAIN或EXPLAIN VERBOSE来查看postgres使用的执行计划。如果您看到类似 SCAN SEQ 的内容,则不使用索引。如果您看到 INDEX SCAN ,则 使用该特定查询的索引。
要在GIS数据上使用索引,必须使用使用geom / geog边界框的函数。 Postgis中的函数使用边界框来使用索引,例如所有operators,或者使用内部运算符进行过滤的一些函数。
我认为你可以做出最好的查询,看看lonlat是否在一个盒子里(你正在尝试做什么?)是这样的:
SELECT *
FROM locations
WHERE
ST_Dwithin(
'POINT('||(longitude*46)||' '||(latitude*69)||')'::geometry,
'POINT(8970 3036)'::geometry
)
(未经测试,但也应与索引一起使用)
答案 1 :(得分:1)
我从你的问题中得到的结论是,你希望在某个点上找到25个单位框内的点数。只要locations
只是点,任何postgres索引(GIN,GiST,b-tree,r-tree等)都可以在此查询中正常运行。如果位置包括一些其他几何形状(细胞塔接收的形状,交付路线区域,等等),那么您需要GiST r树。但总的来说,一个更好的方法,因为我从其他一些问题中得到的印象是地理是你正在做的事情的基础,就是使用PostGIS或至少使用geometry support built into Postgres。您的示例的字面翻译将是:
select * from locations
where my_point_column <@ box '((194.4, 43.36),(194.5 43.6))'
Postgres中的针对具有几何类型的列,而PostGIS版本与针对各种数据的大量改进和实用程序大致相同。