sql - 优化 SQL 距离查询

标签 sql mysql

我正在运行一个根据位置返回结果的 MySQL 查询。但是我最近注意到它确实减慢了我的 PHP 应用程序的速度。我使用了 CodeIgniter,探查器显示查询耗时 4.2 秒。 geoname 表有 500,000 行。我在键列上有一些索引,还有什么可以加快此查询的速度?

这是我的 SQL:

SELECT `products`.`product_name`
     , `geoname`.`geonameid`
     , `geoname`.`latitude`
     , `geoname`.`longitude`
     , `products`.`product_id`
     , AVG(ratings.vote) as rating
     , count(comments.comment_id) as total_comments
     ,   (6371 * acos(cos(radians(38.7666667)) 
               * cos(radians(geoname.latitude)) 
               * cos(radians(geoname.longitude) - radians(-3.3833333)) 
             +   sin(radians(38.7666667)) 
               * sin(radians(geoname.latitude)))
         ) AS distance
FROM (`foods`)
JOIN `geoname` ON `geoname`.`geonameid` = `products`.`geoname_id`
LEFT JOIN `ratings` 
  ON `ratings`.`var_id` = `products`.`product_id`
LEFT JOIN `comments` 
  ON `comments`.`var_id` = `products `.`product_id`
WHERE `products`.`product_id` != 82
GROUP BY `products`.`product_id`
HAVING `distance` < 99
ORDER BY `distance`
LIMIT 10

最佳答案

让我们从查询本身开始 cos(radians(geoname.latitude)) 和其他函数看起来像一个不变量,所以我们可以做一些预处理并将计算值存储在表中。 (计算三角函数主要涉及使用代价高昂的级数展开)。

6371 * acos(cos(radians(38.7666667)) - 这等于 radians(38.76667) * 6371 那么为什么要我们呢?它的成本。

其次,如果您不太关心精度,您可以预先计算弧度本身,比方说从 0 到 pi/2 的 10000 个点 - 这应该给出一个很好的近似值,最多 4 个小数,例如小于 km

(6371 * acos(cos(radians(38.7666667))
 * cos(radians(geoname.latitude))
 * cos(radians(geoname.longitude) - radians(-3.3833333))
+ sin(radians(38.7666667))
* sin(radians(geoname.latitude))))

还记得 sin(a) 当 a > pi/2 且 a < pi 等于 sin(pi - a) 当 a> pi 且 a < 3/2 pi 等于 -sin(a-pi) 并且当 a > 3/2 pi 且 a < 2pi 时等于 -sin (2pi - a)。可以为 cos 函数创建类似的函数。

试试看是否有帮助。 卢克

关于sql - 优化 SQL 距离查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2441757/

相关文章:

sql - 我想获取 SQL Server 中 @ 之前和任何其他特殊字符或空格之后的字符串

mysql - postgresql查询到mysql

java - java和sql如何获取同一列的信息

php - 如何制作现场宏?

mysql - 无法创建将列添加到我指定的任何表的存储过程

mysql查询从一个ID列显示多个表

MySQL Select from 列使用 ^ 作为分隔符

java - Jboss mysql 数据源

mysql - 某个表的外键是否一定要是同一张表的候选键?

sql - BigQuery : Converting key-value pairs in Array to columns