在 mySQL 或 PHP 数组中对结果进行排序?
我正在尝试根据站点访问者与数据库行中列出的位置的距离对 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当您必须处理地理数据时,我可以肯定地推荐带有 PostGIS 扩展的 PostgreSQL。计算纬度和经度之间的距离要快得多。在带有 PostGIS 的 PostgreSQL 中,您的查询将如下所示(未经测试):
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):
The
ST_Distance_Sphere(members.position, ST_GeomFromText("POINT
function gives you the distance between a given point ((47.8012079 13.0395594)", 4326)
POINT
) and the position(47.8012079 13.0395594)
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
两种方法都做并比较结果。这很大程度上取决于您的实际设置。如果您有一个低于标准的数据库服务器和一个强大的网络服务器,那么 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.
在评论中回答 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
我使用一行代码来确定围绕潜在结果的边界框,然后您仅对数据子集运行查询。
例如最大 LNG、最大 LAT、最小 LNG、最小 LAT。
否则,您的 SQL 语句将针对表中的每条记录运行。
我们的应用程序目前有 28000 个位置,因此边界框非常必要!
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!
等等什么?不!如果您返回数千个结果,您可以打赌,在适当配置的 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!