暂无图片
mysql5.7,一个查询执行很慢
我来答
分享
金豆
2021-01-26
mysql5.7,一个查询执行很慢
select a.* from t_3ioj4GeZQU a where status='A' AND batch_Id in( SELECT batch_id from batch_log b LEFT JOIN office o ON b.dept_id = o.ID LEFT JOIN area a on o.AREA_ID = a.ID WHERE target = '21' AND (o.OFFICE_CODE = '130100' or a.AREA_CODE = '130100') ) ORDER BY XK_JDRQ DESC

下面是执行计划:
explain.png

我来答
添加附件
收藏
分享
问题补充
10条回答
默认
最新
金豆

E1.png

暂无图片 评论
暂无图片 有用 0
金豆

E2.png

暂无图片 评论
暂无图片 有用 0
章芋文

t_3ioj4GeZQU表有多少数据量,status='A’有多少数据量,in查询最后的结果集有多少条?,最后满足条件的有多少条数据?

如果不考虑数据量,最大的问题就是从了STATUS的索引,如果batch_Id选择性更好,可以走这个索引。

暂无图片 评论
暂无图片 有用 0
金豆

t_3ioj4GeZQU有106万数据,加A之后68.5万,in的结果集有5.5多数据,耗时90s

暂无图片 评论
暂无图片 有用 0
章芋文

5.5万条吗?

把status,batch_Id的联合索引,换成batch_Id,status试试。

暂无图片 评论
暂无图片 有用 0
金豆

是的5.5多条

暂无图片 评论
暂无图片 有用 0
文成
select a.* from  t_3ioj4GeZQU a
join (
SELECT 
		batch_id from batch_log b 
		LEFT JOIN office o  ON b.dept_id = o.ID
		LEFT JOIN area a on o.AREA_ID = a.ID
		WHERE target = '21' 
	      	AND (o.OFFICE_CODE = '130100' or a.AREA_CODE = '130100')
) aa
 where  status='A' AND batch_Id  aa.batch_Id  
		ORDER BY XK_JDRQ DESC

试试这样

暂无图片 评论
暂无图片 有用 0
金豆

好的,我试一下,谢谢

暂无图片 评论
暂无图片 有用 0
金豆

我发现一个情况,就是不加ORDER BY XK_JDRQ DESC查询只需要6秒多,加了需要60多秒,这种情况是不是给XK_JDRQ 加个索引

暂无图片 评论
暂无图片 有用 0
老紫竹

1、子表里,如果不确认batch_id是唯一的,可以加上distinct
比如
select distinct batch_id from batch_log

2、5.5万行数据,你可以先创建一个临时表,然后再排序分成2步看看性能
create table tmp as select… 不要order
然后单独 select * from tmp order by
看看是否真的和你测试的,order就花费了60秒。

当然你的索引我怀疑没啥用。因为是先通过索引扫描到行,然后内部是并行join,这里数据就被打乱了,最后在join结果集上再排序返回。 原始表的排序列索引预计无效。

怎么看5.5万行也不是很多啊,怎么会花费这么多。是不是内部串行了? 我看资料mysql 8支持并行度。

3、select * 可以减少下字段数量看看,是不是字段太多了导致排序时,花费了额外的时间。如果确认,那也没法办法。

暂无图片 评论
暂无图片 有用 0
回答交流
提交
问题信息
请登录之后查看
邀请回答
暂无人订阅该标签,敬请期待~~
暂无图片墨值悬赏