暂无图片
mysql数据库复杂sql优化问题
我来答
分享
黄伟波
2021-01-28
mysql数据库复杂sql优化问题
暂无图片 5M

生产环境有条慢sql需优化,耗时609s,如下:

	sum( fsl_unrelease_pack_ob_lines.qty ) AS qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty ) AS box_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.release_qty ) AS release_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty - fsl_unrelease_pack_ob_lines.release_qty ) AS unrelease_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty - fsl_unrelease_pack_ob_lines.release_qty ) AS add_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.weight ) AS weight_sum,
	sum( fsl_unrelease_pack_ob_lines.volume ) AS volume_sum 
FROM
	fsl_order_base_line AS fsl_unrelease_pack_ob_lines
	LEFT JOIN fsl_order_base AS ob ON fsl_unrelease_pack_ob_lines.order_base = ob.id 
WHERE
	ob.model1 = 'pack' 
	AND ob.project_code = 'DD' 
	AND fsl_unrelease_pack_ob_lines.domain_name IN ( 'FSL' ) 
	AND fsl_unrelease_pack_ob_lines.origin IN (
	SELECT
		location 
	FROM
		fsl_zone_part t1
		JOIN fsl_location t2 ON t1.zone1 = t2.id 
	WHERE
	t2.NAME = 'xx')

复制

image.png
》》 查看执行计划如下:
image.png

》》表数据量如下:
image.png

》》考虑优化:改写sql+强制索引
这里是考虑小表驱动大表
改写后的sql如下,需强制索引才走对应的执行计划

	sum( fsl_unrelease_pack_ob_lines.qty ) AS qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty ) AS box_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.release_qty ) AS release_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty - fsl_unrelease_pack_ob_lines.release_qty ) AS unrelease_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty - fsl_unrelease_pack_ob_lines.release_qty ) AS add_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.weight ) AS weight_sum,
	sum( fsl_unrelease_pack_ob_lines.volume ) AS volume_sum 
FROM
   fsl_zone_part t1 JOIN fsl_location t2 ON t1.zone1 = t2.id
	join 
	fsl_order_base_line AS fsl_unrelease_pack_ob_lines force index(index_obl_origin) on fsl_unrelease_pack_ob_lines.origin=t1.location
	LEFT JOIN fsl_order_base AS ob ON fsl_unrelease_pack_ob_lines.order_base = ob.id 
WHERE  t2.NAME = '华南'
	 AND ob.model1 = 'pack' 	
				AND  ob.project_code = 'DD' 
	AND fsl_unrelease_pack_ob_lines.domain_name IN ( 'FSL' ) 

复制

执行计划:
image.png

但耗时仍需400s,请问下有进一步优化空间?

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

在原sql只加上强制索引,则耗时150s

	sum( fsl_unrelease_pack_ob_lines.qty ) AS qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty ) AS box_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.release_qty ) AS release_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty - fsl_unrelease_pack_ob_lines.release_qty ) AS unrelease_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.box_qty - fsl_unrelease_pack_ob_lines.release_qty ) AS add_qty_sum,
	sum( fsl_unrelease_pack_ob_lines.weight ) AS weight_sum,
	sum( fsl_unrelease_pack_ob_lines.volume ) AS volume_sum 
FROM
	fsl_order_base_line AS fsl_unrelease_pack_ob_lines  force index(index_obl_origin)  
	LEFT JOIN fsl_order_base AS ob ON fsl_unrelease_pack_ob_lines.order_base = ob.id 
WHERE
	ob.model1 = 'pack' 
	AND ob.project_code = 'DD' 
	AND fsl_unrelease_pack_ob_lines.domain_name IN ( 'FSL' ) 
	AND fsl_unrelease_pack_ob_lines.origin IN (
	SELECT
		location 
	FROM
		fsl_zone_part t1
		JOIN fsl_location t2 ON t1.zone1 = t2.id 
	WHERE
	t2.NAME = '华南')

复制

image.png

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

1.看看能不能把 left join 和 in 语句改成 inner join 方式。
2.索引方面能不能用到 组合索引。
因为业务逻辑,这需要调试才能情况。

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

如果是核心查询业务,且使用频繁,还是建议打破范式。
将明细表增加冗余列,比如你的 model1 ,project_code,NAME

总之,最终你的这个业务,只需要fsl_order_base_line 这个表就足够了。

至于维度表改动,比如华南改成了华南地区, 我看你就做次全表update好了,浪费一次,但后面都省了

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


请输入正文
提交
问题信息
请登录之后查看
邀请回答
暂无人订阅该标签,敬请期待~~
暂无图片墨值悬赏