我有一个查询,用于查找按位置排序的结果。结果还必须考虑增值税,因此这也在查询中。遗憾的是,在未缓存的情况下,查询可能需要 4 秒以上的时间才能运行。任何人都可以发现任何明显的问题或建议我可以做些什么来改进它吗?
只是为了澄清查询中发生的情况:
- 距离计算是使用纬度/经度的欧几里德距离
- incvat 字段用于显示包含增值税时的价格
- WHEN / THEN 语句用于将 0 价格放在最底部
查询:
SELECT * , ROUND( SQRT( POW( ( 69.1 * ( company_branch_lat - 52.4862 ) ) , 2 ) + POW( ( 53 * ( company_branch_lng - - 1.8905 ) ) , 2 ) ) , 1 ) AS distance,
hire_car_day + ( hire_car_day * 0.2 * ! hire_car_incvat ) AS hire_car_day_incvat,
hire_car_addday + ( hire_car_addday * 0.2 * ! hire_car_incvat ) AS hire_car_addday_incvat,
hire_car_week + ( hire_car_week * 0.2 * ! hire_car_incvat ) AS hire_car_week_incvat,
hire_car_weekend + ( hire_car_weekend * 0.2 * ! hire_car_incvat ) AS hire_car_weekend_incvat
FROM hire_car
LEFT JOIN company_branch ON company_branch_id = hire_car_branchid
LEFT JOIN hire_cartypelink ON hire_cartypelink_carhireid = hire_car_id
LEFT JOIN users ON company_branch_userid = user_id
WHERE 1
GROUP BY hire_car_id
HAVING distance <=30
ORDER BY CASE hire_car_day_incvat
WHEN 0
THEN 40000
ELSE hire_car_day_incvat
END , distance ASC
LIMIT 0 , 30
您可以使用 mysql 空间扩展,将纬度和经度保存为点数据类型,并将其设为空间索引。这样您就可以沿曲线重新排序坐标并减小尺寸并保留空间信息。您可以使用空间索引作为边界框来过滤查询,然后使用 Harvesine 公式来选择最佳结果。您的边界框应该大于大圆的半径。 Mysql 使用带有一些空间索引的 rtree,我的示例是关于 z 曲线或希尔伯特曲线:https://softwareengineering.stackexchange.com/questions/113256/what-is-the-difference- Between-btree-and-rtree-indexing。
然后您可以将地理坐标直接插入到点列中:http://dev.mysql.com/doc/refman/5.0/en/creating-spatial-values.html。或者您可以使用几何数据类型:http://markmaunder.com/2009/10/10/mysql-gis-extensions-quick-start/。然后你可以像这样使用 MBRcontains 函数:http://dev.mysql.com/doc/refman/4.1/en/relations-on-geometry-mbr.html或任何其他功能:http://dev.mysql.com/doc/refman/5.5/en/functions-for-testing-spatial-relations- Between-geometric-objects.html。因此你需要一个边界框。
这里有些例子:
-
使用空间点类型在 MySQL 中存储 Lat Lng 值
- https://gis.stackexchange.com/questions/28333/how-to-speed-up-this-simple-mysql-points-in-the-box-query
这是一个使用点数据类型的简单示例:
CREATE SPATIAL INDEX sx_place_location ON place (location)
SELECT * FROM mytable
WHERE MBRContains
(
LineString
(
Point($x - $radius, $y - $radius),
Point($x + $radius, $y + $radius)
)
location
)
AND Distance(Point($x, $y), location) <= $radius
我不确定它是否有效,因为它使用带有边界框函数的半径变量。在我看来 MBRwithin 更简单一些,因为它不需要任何参数:Mysql:优化在嵌套集合树中查找超级节点.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)