我有一个Oracle表12K记录/gyms,下面的查询大约需要0.3秒:
SELECT (acos(sin(41.922682*0.017453293) *
sin(to_number(LATITUDE)*0.017453293) + cos(41.922682*0.017453293) *
cos(to_number(LATITUDE)*0.017453293) * cos(to_number(LONGITUDE)*0.017453293 -
(-87.65432*0.017453293)))*3959) as distance
FROM gym
但是,我想返回距离<=为10的所有记录,并且只要我运行以下查询,我的查询执行时间就会跳到~5.0s:
SELECT * from (SELECT (acos(sin(41.922682*0.017453293) *
sin(to_number(LATITUDE)*0.017453293) + cos(41.922682*0.017453293) *
cos(to_number(LATITUDE)*0.017453293) * cos(to_number(LONGITUDE)*0.017453293 -
(-87.65432*0.017453293)))*3959)
as distance FROM gym)
WHERE distance <= 10
ORDER BY distance asc
你知道如何在Oracle中优化这一点吗?
发布于 2012-02-24 19:14:09
最重要的是:
作为一个非常粗略的近似,你可以使用0.1度作为规则,这是11公里在赤道,而其他地方更少,因此添加
WHERE (longitude - -87.65)<0.1 and (latitude - 41.922)<0.1
(如果您使用嵌套查询,请将此添加到最深层)
其他事情:
如果没有索引,
发布于 2012-02-24 18:12:34
用钱。具体地说,Oracle Spatial。
发布于 2012-02-24 19:23:37
1)如何测量第一个查询的0.3秒?我敢打赌,您测量的是获取第一行所需的时间,而不是获取最后一行所需的时间。如果可能的话,大多数客户端工具将在数据库完成生成结果之前很久就开始显示结果(如果没有ORDER BY
,几乎可以肯定)。因此,您可能正在测量第一个查询计算到前50个或500个健身房的距离所需的时间,而最后一个查询计算到所有12,000个健身房的距离所需的时间。
2) Oracle Locator是Oracle数据库的所有版本都附带的一个特性,它包括使用空间索引的能力,并提供了计算距离的内置方法。它远不如Oracle Spatial强大,但对于您在这里讨论的内容来说,它应该已经足够了。
3)如果你想使用你自己的,我同意johanvdw的建议,使用bounding box。
https://stackoverflow.com/questions/9435834
复制