Ste*_*son 4 mysql performance geospatial database-performance
我有一个查询返回所有记录,与我的 MySQL 5.7 数据库中的字段相比,按距固定点的距离排序POINT。
举一个简单的例子,假设它看起来像这样:
SELECT shops.*, st_distance(location, POINT(:lat, :lng)) as distanceRaw
FROM shops
ORDER BY distanceRaw
LIMIT 50
Run Code Online (Sandbox Code Playgroud)
我的实际查询还必须执行一些连接才能获取结果的附加数据。
问题是,为了按距离对数据进行排序,需要计算数据库中每条记录(目前约为 100,000 条记录)的距离。
我无法缓存查询,因为它仅特定于那些原始坐标。
是否有办法限制必须计算的数据?例如,对附近商店进行可靠的粗略计算,例如lat+ lng? +/- 3 度。那么它只需要处理数据的子集?
如果有人有这种优化的经验,我希望得到一些建议,谢谢。
是的,您可以在 where 标准中使用一些简单的近似来过滤掉那些明显超出半径的位置。这篇题为“SQL(MySQL、PostgreSQL、SQL Server)的快速最近位置查找器”的精彩博客文章描述了此类优化:
请记住,根据本文前面的背景信息,纬度为 111.045 公里。因此,如果我们的纬度列上有索引,我们可以使用这样的 SQL 子句来消除太北或太南而可能在 50 公里以内的点。
latitude BETWEEN latpoint - (50.0 / 111.045) AND latpoint + (50.0 / 111.045)这个 WHERE 子句允许 MySQL 在计算半正矢距离公式之前使用索引省略大量纬度点。它允许 MySQL 对纬度索引执行范围扫描。
最后,我们可以使用类似但更复杂的 SQL 子句来消除太东或太西的点。该条款更为复杂,因为我们距离赤道越远,经度的距离就越小。这就是公式。
longitude BETWEEN longpoint - (50.0 / (111.045 * COS(RADIANS(latpoint)))) AND longpoint + (50.0 / (111.045 * COS(RADIANS(latpoint))))因此,将所有内容放在一起,此查询会查找 (latpoint,longpoint) 50 公里边界框内的最近 15 个点。
上面描述了边界矩形的理论背景。