减少从MYSQL数据库获取数据的时间(表150000中的记录)
请帮我把这个整理一下 我有一个数据库,其中我有150000个商业记录,每个商业记录都有自己的商业类别(例如:酒吧、酒吧、餐厅) 我使用此SQl根据访问者的位置获取类别列表减少从MYSQL数据库获取数据的时间(表150000中的记录),mysql,yii2,Mysql,Yii2,请帮我把这个整理一下 我有一个数据库,其中我有150000个商业记录,每个商业记录都有自己的商业类别(例如:酒吧、酒吧、餐厅) 我使用此SQl根据访问者的位置获取类别列表 SELECT ROUND(6371*acos(cos(radians('52.28231599999999'))*cos(radians(bizprof.vLatitude))*cos(radians(bizprof.vLongitude)-radians('-1.584927'))+sin(radians('52.2823
SELECT
ROUND(6371*acos(cos(radians('52.28231599999999'))*cos(radians(bizprof.vLatitude))*cos(radians(bizprof.vLongitude)-radians('-1.584927'))+sin(radians('52.28231599999999'))*sin(radians(bizprof.vLatitude))),2) AS distance,
`bizcat`.`vCategoryName`,
`bizcat`.`iCategoryId` FROM `business_profile` `bizprof`
LEFT JOIN `users` `u` ON u.iUserId = bizprof.iUserId
AND u.tiIsProfileSet = 1
AND u.tiIsActive = 1
AND u.tiIsDeleted = 0
LEFT JOIN `business_categories` `bizcat` ON bizcat.iCategoryId = bizprof.iCategoryId
GROUP BY `bizcat`.`iCategoryId`
HAVING distance >= 0 AND distance <= 10
选择
圆(6371*acos(弧度('52.2823519999999'))*cos(弧度('bizprof.vLatitude))*cos(弧度('bizprof.vlongity'))-radians('-1.584927'))+sin(弧度('52.28235199999999'))*sin(弧度('bizprof.vLatitude)),2)作为距离,
`bizcat`.`vCategoryName`,
`bizcat`.`iCategoryId`来自'business_profile``bizprof`
在u.iUserId=bizprof.iUserId上左键连接`users``u`
和u.tiIsProfileSet=1
u.tiIsActive=1
和u.tiIsDeleted=0
在bizcat.iCategoryId=bizprof.iCategoryId上左键加入'business_categories'`bizcat'
按'bizcat'分组。'iCategoryId`
距离>=0和距离只是一些建议。。
确保你有合适的compisite索引
表业务配置文件列(iUserId、iCategoryId)
表用户列(iUserId、tiIsProfileSet、tiIsActive、tiIsDeleted)
表“业务类别”列(iCategoryId)
然后,您不应该在不使用聚合函数的情况下使用GROUPBY(如果您需要distinct result,请在select中添加distinct子句)
您还可以使用where(针对距离的重复di代码)子句,而不使用having作为结果过滤器
SELECT
ROUND(6371*acos(cos(radians('52.28231599999999'))*cos(radians(bizprof.vLatitude))*cos(radians(bizprof.vLongitude)-radians('-1.584927'))+sin(radians('52.28231599999999'))*sin(radians(bizprof.vLatitude))),2) AS distance,
`bizcat`.`vCategoryName`,
`bizcat`.`iCategoryId`
FROM `business_profile` `bizprof`
LEFT JOIN `users` `u` ON u.iUserId = bizprof.iUserId
AND u.tiIsProfileSet = 1
AND u.tiIsActive = 1
AND u.tiIsDeleted = 0
LEFT JOIN `business_categories` `bizcat` ON bizcat.iCategoryId = bizprof.iCategoryId
WHERE ROUND(6371*acos(cos(radians('52.28231599999999'))*cos(radians(bizprof.vLatitude))*cos(radians(bizprof.vLongitude)-radians('-1.584927'))+sin(radians('52.28231599999999'))*sin(radians(bizprof.vLatitude))),2) >= 0
AND ROUND(6371*acos(cos(radians('52.28231599999999'))*cos(radians(bizprof.vLatitude))*cos(radians(bizprof.vLongitude)-radians('-1.584927'))+sin(radians('52.28231599999999'))*sin(radians(bizprof.vLatitude))),2) <= 10
选择
圆(6371*acos(弧度('52.2823519999999'))*cos(弧度('bizprof.vLatitude))*cos(弧度('bizprof.vlongity'))-radians('-1.584927'))+sin(弧度('52.28235199999999'))*sin(弧度('bizprof.vLatitude)),2)作为距离,
`bizcat`.`vCategoryName`,
`bizcat`.`iCategoryId`
从'business_profile'`bizprof`
在u.iUserId=bizprof.iUserId上左键连接`users``u`
和u.tiIsProfileSet=1
u.tiIsActive=1
和u.tiIsDeleted=0
在bizcat.iCategoryId=bizprof.iCategoryId上左键加入'business_categories'`bizcat'
其中,圆形(6371*acos(弧度('52.282315999999'))*cos(弧度('bizprof.vLatitude))*cos(弧度('1.584927'))+sin(弧度('52.282315999999'))*sin(弧度('bizprof.vLatitude)),2)>=0
和圆形(6371*acos(弧度('52.2823519999999'))*cos(弧度('bizprof.vLatitude))*cos(弧度('bizprof.vLongitude'))-radians('-1.584927'))+sin(弧度('52.28235199999999'))*sin(弧度('bizprof.vLatitude)),2)
使用及
将和u.tiIsProfileSet=1、u.tiIsActive=1和u.tiIsDeleted=0移动到其中
条件
避免第三次连接,使用另一个查询(通过关系,例如)从业务类别
获取数据
尝试执行此查询
SELECT
ST_Distance_Sphere(Point('-1.584927','52.28231599999999'), Point(`bizprof`.`vLongitude`,`bizprof`.`vLatitude`), 6370986 ) AS `distance`,
`bizprof`.`iCategoryId`
FROM `business_profile` `bizprof`
LEFT JOIN `users` `u` ON `u`.`iUserId` = `bizprof`.`iUserId`
WHERE 1=1
AND `u`.`tiIsProfileSet` = 1
AND `u`.`tiIsActive` = 1
AND `u`.`tiIsDeleted` = 0
HAVING distance >= 0 AND distance <= 10*1000
选择
ST_Distance_Sphere(点('-1.584927','52.2823519999999'),点('bizprof`.'Vlongite`,'bizprof`.'Vlatude`),6370986)表示距离,
`bizprof`.`iCategoryId`
从'business_profile'`bizprof`
在'u'上左键连接'users''u'。'iUserId`='bizprof`.'iUserId``
其中1=1
和'u`.'tiIsProfileSet`=1
和'u`.'tiIsActive`=1
和'u`.'tiIsDeleted`=0
如果距离大于等于0,并且距离没有一个。另外,请告诉我们,网络的速度是多少,你正在拖动这些数据,有多少条记录来自分组,一条记录中大约有多少字节,需要多长时间:首先,在mysql查询中停止计算,如果可能的话,在php中在查询之外计算它们,例如cos(弧度)('52.2823519999999'))
,sin(弧度('52.2823519999999'))
,弧度('-1.584927'))
,第二件事是分析您的表并为正在搜索的列添加适当的索引,当添加正确的索引时,select中可能会有巨大的差异,@MuhammadOmerAslam,为了更好地理解Inexes,您能分享一些好文章吗?谢谢您的查询建议。您能帮我了解一下吗为什么我们要使用这个ST_Dustance_Sphere ad我用Haversian公式来计算距离,在where条件下1=1
这意味着什么?我知道,我不像你那么熟悉,但它帮助我利用我的知识1=1
只用于格式化,你可以跳过它。MySQL 5.7引入ST_distance_Sphere which比原始sql Haversine公式快一点。请看为什么建议将条件从联接移动到何处?
上的子句用于指定如何联接表的条件,而WHERE
子句限制要在结果集中包括哪些行。@rob006请阅读参考手册,因为我有距离>=0和距离在结果上的have工作..so在h之后执行,其中ad select子句..where直接在行上执行..因此为了更好地在行上执行筛选器,不要选择所有行并筛选结果..在您的情况下,have的使用只是为了避免代码重复,但不是这样表现不错希望很明确