oracle地理编码查询真的很慢,我如何优化动态字段?

发布于 2025-01-08 12:23:21 字数 742 浏览 5 评论 0原文

我有一个 Oracle 表 12K 记录/健身房,下面的查询大约需要大约 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.0 秒:

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 中优化它吗?

I have an Oracle table 12K records/gyms, and the query below takes approximately ~0.3s:

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

However, I would like to return all of the records where distance <= 10, and as soon as I run the following query, my query execution time jumps up to ~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

Any idea how I can optimize this in Oracle?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

来世叙缘 2025-01-15 12:23:21

最重要的是:

  • 使用 where 子句排除距您的点超过 10 公里/英里 (?) 的所有经度和纬度。因此,您只需计算 10 公里/英里范围内的窗口即可。

作为一个非常粗略的近似值,您通常可以使用 0.1 度,赤道处为 11 公里,其他地方则更少
所以添加

 WHERE (longitude - -87.65)<0.1 and (latitude - 41.922)<0.1

(如果您使用嵌套查询,请将其添加到最深的级别)

  • 由于您的距离小于10公里或英里,您可以将一个单位纬度/经度的长度视为常数,并使用您的公式计算一次。您可以使用毕达哥拉斯法则来计算距离(添加边界框后)。这基本上就是人们通常使用投影数据进行计算的原因。

其他事情:

  • 如果没有索引,排序总是很慢。需要订购吗?
  • 将经度和纬度保存为表格中的数字。为什么要将它们以不同的方式存储在数据库中?

Most important:

  • use a where clause to exclude all longitudes and latitudes that will be more than 10 km/miles (?) away from your point. So you only need to make your calculation for the window within a 10km/miles block.

as an and very rough approximation you could use 0.1 degree as a rule, this is 11km at the equator,and less elsewhere
so add

 WHERE (longitude - -87.65)<0.1 and (latitude - 41.922)<0.1

(If you use nested queries, add this to the deepest level)

  • Since your distance is smaller than 10 km or mile, you can consider the length of one unit latitude/longitude as constant, and calculate them once using your formula. Than you can use pythagoras rule to calculate the distance (after adding the bounding box). This is basically why people usually use projected data for calculations.

Other things:

  • order by is always slow if you don't have an index. Do you need to order?
  • save your longitude and latitude as numbers in your table. Why would you store them different in a database?
羅雙樹 2025-01-15 12:23:21

有钱。具体来说,是 Oracle Spatial。

With money. Specifically, Oracle Spatial.

旧夏天 2025-01-15 12:23:21

1) 你如何测量第一个查询的 0.3 秒?我敢打赌,您正在测量获取第一行所需的时间,而不是获取最后一行所需的时间。如果可能的话,大多数客户端工具都会在数据库完成生成结果之前很久就开始显示结果(如果没有 ORDER BY,则几乎肯定是这样)。因此,您可能正在测量第一个查询计算到前 50 个或 500 个健身房的距离所需的时间,以及最后一个查询计算到所有 12,000 个健身房的距离所需的时间。

2) Oracle Locator 是所有Oracle 数据库的多个版本,包括使用空间索引的功能并提供计算距离的内置方法。它不如 Oracle Spatial 强大,但对于您在这里讨论的内容来说应该绰绰有余。

3)如果你想推出自己的,我会赞同johanvdw的建议,即使用边界框

1) How are you measuring 0.3 seconds for the first query? I'll wager that you are measuring the time required to fetch the first row rather than the time required to fetch the last row. Most client tools will start displaying results long before the database has finished producing them if that is possible (which it almost certainly is if there is no ORDER BY). So you're probably measuring the time required by the first query to calculate the distance to the first 50 or 500 gyms against the time required by the last query to calculate the distance to all 12,000 gyms.

2) Oracle Locator is a feature that comes with all editions of the Oracle database that includes the ability to use spatial indexes and that provides built-in methods for computing distance. It's not nearly as powerful as Oracle Spatial but it should be more than sufficient for what you're discussing here.

3) If you want to roll your own, I'd second johanvdw's suggestion of using a bounding box.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文