如何减少使用或者不用LEFT JOIN查询?

问题描述:

1、MYSQL语句如下,一大堆的LEFT JOIN,外加一个in的大数组,查询很慢,效率差,如何改造呢?

2、explain不起作用了。

3、采用MYSQL递归查询找出所有下级的方式原来试过,但是不好用,出现的问题是,比如说:前面注册了10个用户,后面再注册1个用户,也就是第11个用户的时候必须是前面用户的下级,要是是他们的上级那就找不出来了,怎么解决?

SELECT COUNT(*) FROM `t_sales`
LEFT JOIN `t_user` ON `t_sales`.`t_for_sale` = `t_user`.`t_id` 
LEFT JOIN `company` ON `t_sales`.`company_id` = `company`.`id` 
LEFT JOIN `t_city_2` ON `t_sales`.`t_city` = `t_city_2`.`t_id` 
LEFT JOIN `t_sales_from` ON `t_sales`.`t_from` = `t_sales_from`.`t_id` 
LEFT JOIN `t_sales_status` ON `t_sales`.`t_status` = `t_sales_status`.`t_id`
LEFT JOIN `custom_category` ON `t_sales`.`t_fenlei` = `custom_category`.`id` 
WHERE `t_for_sale` 
IN ('216', '220', '4507', '4508', '4509', '4510', '4511', '4629', '5292', 
'5602', '6186', '6187', '7018', '301', '337', '2770', '1114', '2144', '2482',
 '2587', '336', '2848', '3386', '1910', '1970', '955', '3148', '3924', '3951',
 '4302', '4467', '5374', '5668', '5736', '6041', '6092', '6093', '6130', '6131',
 '6470', '6662', '3091', '6663', '6793', '6882', '7058', '7059', '1992', '2642',
 '3620', '3639', '3882', '3917', '4446', '4948', '6244')

语句LEFT JOIN和IN的目的:

LEFT JOIN
1、根据id获取它表对应name。(注意:可能存在一对多,或者多对多的关系)
IN
2、查找我所有下属的数据。

计划改造方案

1、原表结构设计不动,把LEFT JOIN去掉,然后把每一个类型,比如:上面的城市t_city_2数据全部取出来,然后在列表输出的时候通过键值对去匹配输出name。

2、IN方面的处理打算采用EXISTS。效率是不是会高一些?

建议或意见收集

1、针对以上的问题希望能在这里找到答案。

2、关于我们的计划改造方案有何不足之处吗?

阅读 12.4k
4 个回答

单独查询,使用键值对

很简单也很实用的一个方案就是建立中间表, 用空间换时间。

另外当数据量大到一定程度情况下,考虑分库分表,可以看看mycat中间件。

个人建议先一个个表排除看是哪个表影响查询的速度,确定是哪个表之后,然后再根据其做索引优化

从数据库优化角度出发,最后结果就一个数count(*)大量的关联导致内存消耗跟时间浪费.

给个思路吧:
将sql结果做成如下:

clipboard.png

最后count(*)等于每一行数量相乘最后相加,
即:(数量11*数量12*...*数量16)+(数量21*...*数量26)
以减少大量的笛卡尔积.

sql:

select t_for_sale.id,  nvl(t1.count1, 0), ...
left join (select id, count(*) count1 from t_user group by id) t1 on t1.id=t_for_sale.id
....
from t_for_sale
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题