暂无图片
MySQL sql优化 问题
我来答
分享
黄伟波
2020-10-16
MySQL sql优化 问题
暂无图片 5M

今天看到一条sql,感觉不太好优化,放出来集思广益…
问题sql

EXPLAIN SELECT
	x.id,
	x.version,
	x.order_no1,
	x.order_status,
	x.delivery_status,
	x.delivery_time,
	y.delivery_status AS _delivery_status,
	y.unload_time AS _unload_time 
FROM
	fsl_order_base x
	JOIN (
	SELECT
		( CASE WHEN delivery_qty = qty THEN 2 WHEN delivery_qty < qty THEN 1 ELSE 0 END ) delivery_status,
		order_no1,
		unload_time 
	FROM
		(
		SELECT
			SUM( t2.box_qty ) delivery_qty,
			SUM( t1.qty ) qty,
			t.order_no1,
			MAX( t4.unload_time ) unload_time 
		FROM
			fsl_order_base t
			LEFT JOIN fsl_order_base_line t1 ON t.id = t1.order_base
			LEFT JOIN fsl_order_unit_box t2 ON t2.order_base_line = t1.id
			JOIN (
			SELECT
				id,
				dest,
				shipment,
				order_unit,
				unload,
				unload_time 
			FROM
				fsl_order_movement_unit 
			WHERE
				unload = TRUE 
				AND datediff( now( ), unload_time ) < 30 
			) t4 ON t2.order_unit = t4.order_unit
			JOIN fsl_shipment t6 ON t4.shipment = t6.id 
			AND t6.is_a_shipment = 'Y'
			JOIN fsl_shipment_stop t5 ON t5.id = t4.dest 
			AND t5.location = t1.dest 
		WHERE
			t.order_status IN ( '1', '2' ) 
			AND ( t.delivery_status <> '2' OR t.delivery_time IS NULL ) 
			AND t.project_code = 'FS' 
		GROUP BY
			t.order_no1 
		) a 
	) y ON x.order_no1 = y.order_no1 
	AND x.project_code = 'FS' 
	AND ( x.delivery_status <> 2 OR x.delivery_time IS NULL ) 
	AND ( x.delivery_status <> y.delivery_status OR x.delivery_time <> y.unload_time )
复制

执行计划如下:
image.png

大佬们给个优化意见和思路?

我来答
添加附件
收藏
分享
问题补充
4条回答
默认
最新
黄伟波

fsl_order_base表,简称t表,t表的,order_status,project_code的区分度都很低,没法建索引

》》t表索引情况
t表建了28个索引
image.png

暂无图片 评论
暂无图片 有用 0
打赏 0
黄伟波

该sql执行了1525s仍无出结果

image.png

暂无图片 评论
暂无图片 有用 0
打赏 0
Cui Hulong

看到sql语句有点太复杂了。explain 看看能不能优化
1.像这样的sql 语句 能用inner join + 主键join方式最好
2.不要进行多表嵌套关联。

优化的力度应该有,但问题依然还会存在,建议拆分。
拆分方式:
1.mysql里join也不好太多,保持两张表
2.inner join + 主键关联
3.小表驱动大表方式

暂无图片 评论
暂无图片 有用 0
打赏 0
chengang

语句太长了。至少有一点可以做很大的优化。因为是inner join
所以你x表的所有过滤应该都可以写在嵌套查询的t表上进行过滤

暂无图片 评论
暂无图片 有用 0
打赏 0
回答交流
Markdown


请输入正文
提交
相关推荐
我定义了一个名为IP的变量,要在红框处引用它,应该怎么写?
回答 2
“string”类型就可以了,执行的时候要直接暴露出来不要有’‘之类的
关闭mysql的binlog,这时redolog是一阶段还是仍走两阶段?
回答 1
等于你没开归档。开了binlog,还要有几个参数结合才能说。现在关了,等于你没开归档。什么都不用谈了。
mysql服务器未运行情况下内存占比很高
回答 4
已采纳
经过自己的摸索,问题已解决!内存占用是hugepages导致的,修改/etc/sysctl.conf下面的文件:vm.nrhugepages4760vm.hugetlbshmgroup1008将上面两
mysql 故障处理
回答 8
亚秒是个啥时间单位,要不去机房拔电吧,一下子清静了
以下哪些不是MySQL数据类型?
回答 6
已采纳
应该是前两个吧。BIGDATEBIGCHAR
Mysql WorkBench 修改不了表结构,怎么解决?
回答 1
已采纳
这是新创建的表,还是里边有数据,里边有数据的话确认下是否数据有字幕之类的。
MySQL online ddl还是用pt-osc吗?
回答 2
mysqlonlineddl涉及的场景不够全面,有些调整字段类型的场景仍会锁表,此时需要psosc处理
linux 6.8 mysql建议什么版本比较稳定?
回答 1
已采纳
是CentOS6.8吗?MySQL5.7和8都行。越新的越好一些,毕竟修复了漏洞和BUG。但是不排除有新的问题。最主要的还是SQL质量。SQL好的用5.6也行,SQL不好的用Oracle也不行。
隐式转换
回答 1
At2.col1为utf8字符集,t1.col1为utf8mb4字符集Bt2.col1为varchar型,t1.col1为bigint型Dt2.col1为varchar型,t1.col1为int型
MYSQL的表有碎片的整理操作 alter ...engine=innodb 是否支持在线操作??
回答 1
支持,但是建议业务低峰期执行