有没有办法优化在每一行上运行函数的 MySQL 查询?

发布于 2024-09-06 08:24:36 字数 703 浏览 1 评论 0原文

我有一个 MySQL 查询,它根据标准从数据库中提取经纬度,测试这些点是否在多边形内,并返回多边形内的点。

一切正常。问题是查询大约需要花费时间。 20秒返回结果。有没有办法优化这个查询,让查询速度更快?

SELECT latitude, longitude
FROM myTable
WHERE offense = 'green' AND myWithin(
POINTFROMTEXT( CONCAT( 'POINT(', latitude, ' ', longitude, ')' ) ) , POLYFROMTEXT( 'POLYGON(( ...bunch of lat longs...))' )
) = 1;

我运行了 EXPLAIN SELECT... 产生了

id |选择类型 |表|类型 | 可能的键 |关键| key_len |参考| 行 |额外

1 SIMPLE myTable ALL NULL NULL NULL NULL 137003 使用 where

是否有一种方法可以优化在数据库中的每个纬度和经度上运行的查询,或者这是否已经达到最佳状态?

我正在考虑对另一个表进行选择,然后查询结果表,但我希望有一种方法可以提高此查询的性能。

如果有人有任何建议或想法,我很想听听。

谢谢,

拉克斯米迪

I've got a MySQL query that pulls lat longs from a database based on a criterion, tests whether these points are within a polygon, and returns the points that are within the polygon.

Everything works fine. The problem is that the query takes approx. 20 seconds to return a result. Is there a way to optimize this query so that query speed is faster?

SELECT latitude, longitude
FROM myTable
WHERE offense = 'green' AND myWithin(
POINTFROMTEXT( CONCAT( 'POINT(', latitude, ' ', longitude, ')' ) ) , POLYFROMTEXT( 'POLYGON(( ...bunch of lat longs...))' )
) = 1;

I ran an EXPLAIN SELECT... which produced

id | select_type | table | type |
possible_keys | key | key_len | ref |
rows | Extra

1 SIMPLE myTable ALL NULL NULL NULL NULL 137003 Using where

Is there a way to optimize a query that is run on every latitude and longitude in the db or is this as good as it gets?

I'm thinking about doing a select into another table and then querying the results table, but I was hoping that there would be a way to improve the performance of this query.

If anyone has any suggestions or ideas, I'd love to hear them.

Thanks,

Laxmidi

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

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

发布评论

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

评论(2

一梦浮鱼 2024-09-13 08:24:36

多边形有多大?您可以在整个多边形周围定义一个“边界矩形”,然后执行以下操作:

SELECT latitude, longitude
FROM myTable
WHERE
  offense = 'green' AND
  latitude BETWEEN rect_left AND rect_right AND
  longitude BETWEEN rect_top AND rect_bottom AND
  myWithin(
    POINTFROMTEXT( CONCAT( 'POINT(', latitude, ' ', longitude, ')' ) ),
    POLYFROMTEXT( 'POLYGON(( ...bunch of lat longs...))' )) = 1;

这样,它可以使用纬度和经度上的索引来缩小必须运行复杂内容的点的数量。

How big are the polygons? You could define a "bounding rectangle" around the whole polygon and then do:

SELECT latitude, longitude
FROM myTable
WHERE
  offense = 'green' AND
  latitude BETWEEN rect_left AND rect_right AND
  longitude BETWEEN rect_top AND rect_bottom AND
  myWithin(
    POINTFROMTEXT( CONCAT( 'POINT(', latitude, ' ', longitude, ')' ) ),
    POLYFROMTEXT( 'POLYGON(( ...bunch of lat longs...))' )) = 1;

That way, it could use an index on latitude and longitude to narrow down the number of points that it has to run the complex stuff on.

幸福丶如此 2024-09-13 08:24:36

我看到两个明显的优化途径:

  • 在运行函数 O(n) 次之前减少结果集。现在您正在运行该函数 137003 次 - 如果您无法进一步过滤结果集,则几乎没有办法避免这种情况。

  • 使函数更快,这样您仍然运行它 137k 次,但每次调用花费的时间更少,从而减少总运行时间。

现在,您的函数每行运行需要 0.1459 毫秒,这确实不错。您可能想尝试找到某种方法来进一步减少必须运行它的行数。通过巧妙使用 WHERE 来减少结果集还有一个附带的好处,即允许数据库为您进行一些优化,这就是您希望使用它的方式。

I see two obvious avenues for optimization:

  • Reduce the result set more before you run your function O(n) times. Right now you're running the function 137003 times - there's little way to avoid that if you can't filter the result set any further.

  • Make the function faster, such that you're still running it 137k times, but each invocation takes less time, thus reducing your total runtime.

Right now your function is taking 0.1459 milliseconds per row to run, which really isn't bad. You probably want to try to find some way to further reduce the number of rows you have to run it on. Reducing the result set through clever use of WHERE also has the side benefit of allowing your database to do some optimization for you, which is how you want to be using it.

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