在 mySQL 或 PHP 数组中对结果进行排序?

发布于 2024-11-08 12:34:47 字数 439 浏览 0 评论 0 原文

我正在尝试根据站点访问者与数据库行中列出的位置的距离对 mySQL 结果进行排序。我应该在 mySQL 中进行排序并获取排序后的结果,还是从 mySQL 数据库中检索未排序的结果然后使用 PHP 进行排序?我的性能有区别吗?

如果我使用 mySQL 排序,这是我将使用的 SQL 代码。

SELECT ((ACOS(SIN($lat * PI() / 180) * SIN(lat * PI() / 180) 
+ COS($lat * PI() / 180) * COS(lat * PI() / 180) * COS(($lon – lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) 
AS `distance` FROM `members` HAVING `distance`<=’10′ ORDER BY `distance` ASC

I am trying to sort a mySQL results by distance of site visitor from places listed in the database rows. Should I do the sorting in mySQL and get the sorted results, or retrieve the unsorted results from mySQL database then sort using PHP? Is there a difference i performance?

This is the SQL code I will use if I sort using mySQL.

SELECT ((ACOS(SIN($lat * PI() / 180) * SIN(lat * PI() / 180) 
+ COS($lat * PI() / 180) * COS(lat * PI() / 180) * COS(($lon – lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) 
AS `distance` FROM `members` HAVING `distance`<=’10′ ORDER BY `distance` ASC

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

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

发布评论

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

评论(5

心是晴朗的。 2024-11-15 12:34:47

当您必须处理地理数据时,我可以肯定地推荐带有 PostGIS 扩展的 PostgreSQL。计算纬度和经度之间的距离要快得多。在带有 PostGIS 的 PostgreSQL 中,您的查询将如下所示(未经测试):

SELECT *
FROM members
WHERE ST_Distance_Sphere(members.position, ST_GeomFromText("POINT
(47.8012079 13.0395594)", 4326) <= 10000
ORDER BY ST_Distance_Sphere(members.position, ST_GeomFromText("POINT
(47.8012079 13.0395594)", 4326)

ST_Distance_Sphere(members.position, ST_GeomFromText("POINT
(47.8012079 13.0395594)", 4326) 函数给出给定点 (POINT
(47.8012079 13.0395594)
) 以及您会员的位置members.position。您可以在一条语句中多次使用此函数,PostgreSQL 将为您缓存该函数(并且不会计算两次距离)。

并且不要忘记向您的 members.position 列添加所谓的“空间索引”。看看 http://postgis.refractions.net/http://www.postgresql.org/

如果您在开始使用 postgresql 时遇到困难,网上有很多教程。或者,只是在这里询问;)

问候,
无尾礼服

When you have to deal with geodata, I can defenetly recommend PostgreSQL with the PostGIS extension. It's way faster in calculating distances between lat and lng. In PostgreSQL with PostGIS your query would look like that (untested):

SELECT *
FROM members
WHERE ST_Distance_Sphere(members.position, ST_GeomFromText("POINT
(47.8012079 13.0395594)", 4326) <= 10000
ORDER BY ST_Distance_Sphere(members.position, ST_GeomFromText("POINT
(47.8012079 13.0395594)", 4326)

The ST_Distance_Sphere(members.position, ST_GeomFromText("POINT
(47.8012079 13.0395594)", 4326)
function gives you the distance between a given point (POINT
(47.8012079 13.0395594)
) and the position members.position of your member. You can use this function multiple times within one statement, PostgreSQL will cache that for you (and don't calculate the distance twice).

And don't forget to add a so called "spatial index" to your members.position column. Have a look at http://postgis.refractions.net/ and http://www.postgresql.org/

There are many tutorials around the web, if you have trouble to start with postgresql. Or, just ask here ;)

regards,
tux

遮了一弯 2024-11-15 12:34:47

两种方法都做并比较结果。这很大程度上取决于您的实际设置。如果您有一个低于标准的数据库服务器和一个强大的网络服务器,那么 PHP 可能会更快。如果您有一个超级数据库服务器和一个 486 网络服务器,那么数据库排序可能会更快。这一切都取决于您的设置。

编辑:另外,我建议以弧度存储经度和纬度,这样您就不必在每次想要执行查询时都进行所有这些转换。

Do it both ways and compare the results. This massively depends on your actual setup. If you have a sub-par database server and a kick-ass webserver, then the PHP will probably be quicker. If you have a super database server and a 486 for a webserver, then the database sort could be quicker. It all depends on your setup.

Edit: Also, I suggest storing your longitudes and latitudes in radians so you don't have to do all of those conversions every time you want to do a query.

初相遇 2024-11-15 12:34:47

在评论中回答 Nyxynyx 问题“顺便说一句,如果您查看我发布的查找距离的公式,答案的单位是什么?米?我的输入是 (x.xxxxxx,x.xxxxxx),就像使用的那样在谷歌地图 v3 api 中,我不确定它叫什么?“

您的计算输入是纬度 (lat) 和经度 (lng)

http://en.wikipedia.org/wiki/Geographic_coordinate_system

中查找计算说明

http://en.wikipedia.org/wiki/Great-circle_distance

in answer to Nyxynyx question in a comment "BTW, if you look at my posted formula for finding distances, what is the units the answer is in? Metres? My input is in (x.xxxxxx,x.xxxxxx) like the one used in google maps v3 api. I am not sure what is it called? "

The input of your computation is latitude (lat) and longitude (lng)

http://en.wikipedia.org/wiki/Geographic_coordinate_system

Find an explanation of you computation at

http://en.wikipedia.org/wiki/Great-circle_distance

预谋 2024-11-15 12:34:47

我使用一行代码来确定围绕潜在结果的边界框,然后您仅对数据子集运行查询。

例如最大 LNG、最大 LAT、最小 LNG、最小 LAT。

否则,您的 SQL 语句将针对表中的每条记录运行。

我们的应用程序目前有 28000 个位置,因此边界框非常必要!

class Geo{
function RadiusCheck($lat, $lng, $miles) {
    $EQUATOR_LAT_MILE = 69.172;
    $maxLat = $lat + $miles / $EQUATOR_LAT_MILE;
    $minLat = $lat - ($maxLat - $lat);
    $maxLng = $lng + $miles / (cos($minLat * M_PI / 180) * $EQUATOR_LAT_MILE);
    $minLng = $lng - ($maxLng - $lng);


    $result['minLat']   = $minLat;
    $result['maxLat']   = $maxLat;
    $result['minLng']   = $minLng;
    $result['maxLng']   = $maxLng;

    return $result;
}
}

I use a line of code to determine a bounding box surrounding the potential results then you are only running your query on a subset of data.

Eg max LNG, max LAT, min LNG, min LAT.

Otherwise your SQL statement will run against EVERY record in your table.

Our app has 28000 locations currently so the bounding box is VERY necessary!

class Geo{
function RadiusCheck($lat, $lng, $miles) {
    $EQUATOR_LAT_MILE = 69.172;
    $maxLat = $lat + $miles / $EQUATOR_LAT_MILE;
    $minLat = $lat - ($maxLat - $lat);
    $maxLng = $lng + $miles / (cos($minLat * M_PI / 180) * $EQUATOR_LAT_MILE);
    $minLng = $lng - ($maxLng - $lng);


    $result['minLat']   = $minLat;
    $result['maxLat']   = $maxLat;
    $result['minLng']   = $minLng;
    $result['maxLng']   = $maxLng;

    return $result;
}
}
执妄 2024-11-15 12:34:47

等等什么?不!如果您返回数千个结果,您可以打赌,在适当配置的 mysql 服务器上它会更快。设置适当的索引,存储您的纬度和纬度long 与 CanSpice 建议的弧度一样,并且仅返回您需要的结果...在 mysql 服务器上排序。 @CanSpice 关于检查哪个更快是正确的,但在我看来,如果您的数据库服务器较慢,则说明您配置错误。修复它!

Wait what? No! If you're returning thousands of results you can bet it'll be faster on an appropriately configured mysql server. Set the appropriate indexes, store your lat & long's as radians as CanSpice has suggested, and return only the results you need... sorted on the mysql server. @CanSpice is right about checking which is faster, but in my opinion, if your DB server is slower, you've configured it wrong. Fix it!

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