记录一次MySQL查询优化

WITH `tmp` AS (
	SELECT
		`m`.`FactoryName` AS `FactoryName`,
		`m`.`Spec` AS `Spec`,
		`m`.`MaterialType` AS `MaterialType`,
		`m1`.`ProductionPlanID` AS `ProductionPlanID`,
		`m`.`PurchCycle` AS `PurchCycle`,
		`m`.`MaterialCheckCycle` AS `MaterialCheckCycle`,
		`m`.`WhSumQty` AS `WhSumQty`,
		ifnull( `m`.`SafetyStockQty`, 0 ) AS `SafetyStockQty`,
	IF
		(((((
							ifnull( `m`.`WhSumQty`, 0 ) + ifnull( `m`.`NextArrivalQty`, 0 )) - ifnull( `m`.`ConsumeQty`, 0 )) - ifnull( `m`.`SafetyStockQty`, 0 )) > 0 
				),
			1,
			0 
			) AS `SafeStatus`,(((
				ifnull( `m`.`WhSumQty`, 0 ) + ifnull( `m`.`NextArrivalQty`, 0 )) - ifnull( `m`.`ConsumeQty`, 0 )) - ifnull( `m`.`SafetyStockQty`, 0 )) AS `RemainQty` 
	FROM
		(
			`mm_mrp_dt` `m`
			LEFT JOIN `mm_mrp_main` `m1` ON ((
					`m1`.`MMRPID` = `m`.`MMRPID` 
				))) 
	WHERE
		(
		`m`.`MaterialType` IN ( 1, 2 ))),
	`tmp1` AS (
	SELECT
		`m`.`ProcessID` AS `ProcessID`,
		`m1`.`ScheduleDate` AS `ScheduleDate`,
		`m`.`VendorName` AS `VendorName`,
		`m`.`Spec` AS `Spec`,
		`m2`.`ProductionPlanID` AS `ProductionPlanID`,(
		CASE
				`m`.`ProcessID` 
				WHEN '7F3596F606336B5D' THEN
				'前驱体' ELSE '锂盐' 
			END 
			) AS `Type`,
			sum( `m`.`InspectVal` ) AS `DailyQty`,(
			CASE
					
					WHEN ( `tmp`.`SafeStatus` = 2 ) THEN
					0 ELSE (
					SELECT
						( sum(( CASE WHEN ( `main`.`BillType` = '628' ) THEN -( `dt`.`Qty` ) ELSE `dt`.`Qty` END )) / 1000 ) AS `Qty` 
					FROM
						(((
									`wm_instockbill_dt` `dt`
									LEFT JOIN `wm_instockbill_main` `main` ON ((
											`main`.`InStockBillID` = `dt`.`InStockBillID` 
										)))
								LEFT JOIN `wm_batch` `b` ON ((
										`b`.`BatchID` = `dt`.`BatchID` 
									)))
							LEFT JOIN `bd_vendor` `bd` ON ((
									`b`.`PartnerID` = `bd`.`VendorID` 
								))) 
					WHERE
						((
								`main`.`BillType` IN ( '611', '628' )) 
							AND ( `main`.`Status` = '2' ) 
							AND (
							`main`.`InStockDate` = ( `m1`.`ScheduleDate` - INTERVAL ( `tmp`.`PurchCycle` + `tmp`.`MaterialCheckCycle` ) DAY )) 
							AND ( `dt`.`MaterialID` = `m`.`Spec` ) 
						AND ( `b`.`PartnerID` = `m`.`VendorName` )) 
					GROUP BY
						`main`.`InStockDate`,
						`dt`.`MaterialID`,
						`b`.`PartnerID` 
					) 
				END 
				) AS `ActualQty`,
				`tmp`.`WhSumQty` AS `WhSumQty`,
				`tmp`.`RemainQty` AS `RemainQty`,
				`tmp`.`SafetyStockQty` AS `SafetyStockQty`,
				`tmp`.`PurchCycle` AS `PurchCycle`,
				`tmp`.`MaterialCheckCycle` AS `MaterialCheckCycle` 
			FROM
				(((
							`mm_imitate_schedule_material` `m`
							LEFT JOIN `mm_imitate_schedule_dt` `m1` ON ((
									`m1`.`ScheduleDtID` = `m`.`ScheduleDtID` 
								)))
						LEFT JOIN `mm_imitate_schedule_main` `m2` ON ((
								`m2`.`ScheduleID` = `m`.`ScheduleID` 
							)))
					LEFT JOIN `tmp` ON (((
								`m`.`VendorName` = `tmp`.`FactoryName` 
								) 
							AND ( `tmp`.`MaterialType` = 1 ) 
							AND ( `m`.`Spec` = `tmp`.`Spec` ) 
						AND ( `tmp`.`ProductionPlanID` = `m2`.`ProductionPlanID` )))) 
			WHERE
				( `m`.`ProcessID` = '7F3596F606336B5D' ) 
			GROUP BY
				`m`.`ProcessID`,
				`m1`.`ScheduleDate`,
				`m`.`VendorName`,
				`m`.`Spec`,
				`m2`.`ProductionPlanID` 
			),
			`tmp2` AS (
			SELECT
				`tmp1`.`ProcessID` AS `ProcessID`,(
					`tmp1`.`ScheduleDate` - INTERVAL ( `tmp1`.`PurchCycle` + `tmp1`.`MaterialCheckCycle` ) DAY 
					) AS `ScheduleDate`,(
				SELECT
					group_concat( `bd_vendor`.`VendorName` ORDER BY find_in_set( `bd_vendor`.`VendorID`, `tmp1`.`VendorName` ) ASC SEPARATOR ',' ) 
				FROM
					`bd_vendor` 
				WHERE
					(
					0 <> find_in_set( `bd_vendor`.`VendorID`, `tmp1`.`VendorName` ))) AS `VendorName`,
				`tmp1`.`VendorName` AS `VendorID`,
				`tmp1`.`Spec` AS `Spec`,(
				SELECT
					group_concat( `bd_material`.`MaterialName` ORDER BY find_in_set( `bd_material`.`MaterialID`, `tmp1`.`Spec` ) ASC SEPARATOR ',' ) 
				FROM
					`bd_material` 
				WHERE
					(
					0 <> find_in_set( `bd_material`.`MaterialID`, `tmp1`.`Spec` ))) AS `MaterialName`,
				`tmp1`.`Type` AS `Type`,
				`tmp1`.`DailyQty` AS `DailyQty`,
				`tmp1`.`RemainQty` AS `RemainQty`,
				`tmp1`.`ScheduleDate` AS `ScheduleDate_temp`,
				`tmp1`.`WhSumQty` AS `WhSumQty`,
				`tmp1`.`SafetyStockQty` AS `SafetyStockQty`,
				round( `tmp1`.`ActualQty`, 3 ) AS `ActualQty`,
				concat_ws(
					'_',
					`tmp1`.`ProcessID`,
					`tmp1`.`VendorName`,
					`tmp1`.`Spec`,
				CONVERT ( `tmp1`.`Type` USING utf8 )) AS `UniqeID` 
			FROM
				`tmp1` 
			),
			`tmp11` AS (
			SELECT
				`m`.`ProcessID` AS `ProcessID`,
				`m1`.`ScheduleDate` AS `ScheduleDate`,
				`m`.`VendorName` AS `VendorName`,
				`m`.`Spec` AS `Spec`,
				`m2`.`ProductionPlanID` AS `ProductionPlanID`,(
				CASE
						`m`.`ProcessID` 
						WHEN '7F3596F606336B5D' THEN
						'前驱体' ELSE '锂盐' 
					END 
					) AS `Type`,
					sum( `m`.`InspectVal` ) AS `DailyQty`,(
					CASE
							
							WHEN ( `tmp`.`SafeStatus` = 1 ) THEN
							0 ELSE (
							SELECT
								( sum(( CASE WHEN ( `main`.`BillType` = '628' ) THEN -( `dt`.`Qty` ) ELSE `dt`.`Qty` END )) / 1000 ) AS `Qty` 
							FROM
								(((
											`wm_instockbill_dt` `dt`
											LEFT JOIN `wm_instockbill_main` `main` ON ((
													`main`.`InStockBillID` = `dt`.`InStockBillID` 
												)))
										LEFT JOIN `wm_batch` `b` ON ((
												`b`.`BatchID` = `dt`.`BatchID` 
											)))
									LEFT JOIN `bd_vendor` `bd` ON ((
											`b`.`PartnerID` = `bd`.`VendorID` 
										))) 
							WHERE
								((
										`main`.`BillType` IN ( '611', '628' )) 
									AND ( `main`.`Status` = '2' ) 
									AND (
									`main`.`InStockDate` = ( `m1`.`ScheduleDate` - INTERVAL ( `tmp`.`PurchCycle` + `tmp`.`MaterialCheckCycle` ) DAY )) 
									AND ( `dt`.`MaterialID` = `m`.`Spec` ) 
								AND ( `b`.`PartnerID` = `m`.`VendorName` )) 
							GROUP BY
								`main`.`InStockDate`,
								`dt`.`MaterialID`,
								`b`.`PartnerID` 
							) 
						END 
						) AS `ActualQty`,
						`tmp`.`WhSumQty` AS `WhSumQty`,
						`tmp`.`RemainQty` AS `RemainQty`,
						`tmp`.`SafetyStockQty` AS `SafetyStockQty`,
						`tmp`.`PurchCycle` AS `PurchCycle`,
						`tmp`.`MaterialCheckCycle` AS `MaterialCheckCycle` 
					FROM
						(((
									`mm_imitate_schedule_material` `m`
									LEFT JOIN `mm_imitate_schedule_dt` `m1` ON ((
											`m1`.`ScheduleDtID` = `m`.`ScheduleDtID` 
										)))
								LEFT JOIN `mm_imitate_schedule_main` `m2` ON ((
										`m2`.`ScheduleID` = `m`.`ScheduleID` 
									)))
							LEFT JOIN `tmp` ON (((
										`m`.`VendorName` = `tmp`.`FactoryName` 
										) 
									AND ( `tmp`.`MaterialType` = 2 ) 
									AND ( `m`.`Spec` = `tmp`.`Spec` ) 
								AND ( `tmp`.`ProductionPlanID` = `m2`.`ProductionPlanID` )))) 
					WHERE
						( `m`.`ProcessID` = 'BBECC27125E56409' ) 
					GROUP BY
						`m`.`ProcessID`,
						`m1`.`ScheduleDate`,
						`m`.`VendorName`,
						`m`.`Spec`,
						`m2`.`ProductionPlanID` 
					),
					`tmp12` AS (
					SELECT
						`tmp11`.`ProcessID` AS `ProcessID`,(
							`tmp11`.`ScheduleDate` - INTERVAL ( `tmp11`.`PurchCycle` + `tmp11`.`MaterialCheckCycle` ) DAY 
							) AS `ScheduleDate`,(
						SELECT
							group_concat( `bd_vendor`.`VendorName` ORDER BY find_in_set( `bd_vendor`.`VendorID`, `tmp11`.`VendorName` ) ASC SEPARATOR ',' ) 
						FROM
							`bd_vendor` 
						WHERE
							(
							0 <> find_in_set( `bd_vendor`.`VendorID`, `tmp11`.`VendorName` ))) AS `VendorName`,
						`tmp11`.`VendorName` AS `VendorID`,
						`tmp11`.`Spec` AS `Spec`,(
						SELECT
							group_concat( `bd_material`.`MaterialName` ORDER BY find_in_set( `bd_material`.`MaterialID`, `tmp11`.`Spec` ) ASC SEPARATOR ',' ) 
						FROM
							`bd_material` 
						WHERE
							(
							0 <> find_in_set( `bd_material`.`MaterialID`, `tmp11`.`Spec` ))) AS `MaterialName`,
						`tmp11`.`Type` AS `Type`,
						`tmp11`.`DailyQty` AS `DailyQty`,
						`tmp11`.`RemainQty` AS `RemainQty`,
						`tmp11`.`ScheduleDate` AS `ScheduleDate_temp`,
						`tmp11`.`WhSumQty` AS `WhSumQty`,
						`tmp11`.`SafetyStockQty` AS `SafetyStockQty`,
						round( `tmp11`.`ActualQty`, 3 ) AS `ActualQty`,
						concat_ws(
							'_',
							`tmp11`.`ProcessID`,
							`tmp11`.`VendorName`,
							`tmp11`.`Spec`,
						CONVERT ( `tmp11`.`Type` USING utf8 )) AS `UniqeID` 
					FROM
						`tmp11` 
					),
					`tmpzh` AS (
					SELECT
						`tmp2`.`ProcessID` AS `ProcessID`,
						`tmp2`.`ScheduleDate` AS `ScheduleDate`,
						`tmp2`.`VendorName` AS `VendorName`,
						`tmp2`.`VendorID` AS `VendorID`,
						`tmp2`.`Spec` AS `Spec`,
						`tmp2`.`MaterialName` AS `MaterialName`,
						`tmp2`.`Type` AS `Type`,
						`tmp2`.`DailyQty` AS `DailyQty`,
						`tmp2`.`RemainQty` AS `RemainQty`,
						`tmp2`.`ScheduleDate_temp` AS `ScheduleDate_temp`,
						`tmp2`.`WhSumQty` AS `WhSumQty`,
						`tmp2`.`SafetyStockQty` AS `SafetyStockQty`,
						`tmp2`.`ActualQty` AS `ActualQty`,
						`tmp2`.`UniqeID` AS `UniqeID` 
					FROM
						`tmp2` UNION ALL
					SELECT
						`tmp12`.`ProcessID` AS `ProcessID`,
						`tmp12`.`ScheduleDate` AS `ScheduleDate`,
						`tmp12`.`VendorName` AS `VendorName`,
						`tmp12`.`VendorID` AS `VendorID`,
						`tmp12`.`Spec` AS `Spec`,
						`tmp12`.`MaterialName` AS `MaterialName`,
						`tmp12`.`Type` AS `Type`,
						`tmp12`.`DailyQty` AS `DailyQty`,
						`tmp12`.`RemainQty` AS `RemainQty`,
						`tmp12`.`ScheduleDate_temp` AS `ScheduleDate_temp`,
						`tmp12`.`WhSumQty` AS `WhSumQty`,
						`tmp12`.`SafetyStockQty` AS `SafetyStockQty`,
						`tmp12`.`ActualQty` AS `ActualQty`,
						`tmp12`.`UniqeID` AS `UniqeID` 
					FROM
						`tmp12` 
					),
					`tmp3` AS (
					SELECT
						`tmpzh`.`ProcessID` AS `ProcessID`,
						`tmpzh`.`ScheduleDate` AS `ScheduleDate`,
						`tmpzh`.`VendorName` AS `VendorName`,
						`tmpzh`.`VendorID` AS `VendorID`,
						`tmpzh`.`Spec` AS `Spec`,
						`tmpzh`.`MaterialName` AS `MaterialName`,
						`tmpzh`.`Type` AS `Type`,
						`tmpzh`.`DailyQty` AS `DailyQty`,
						`tmpzh`.`RemainQty` AS `RemainQty`,
						`tmpzh`.`ScheduleDate_temp` AS `ScheduleDate_temp`,
						`tmpzh`.`WhSumQty` AS `WhSumQty`,
						`tmpzh`.`SafetyStockQty` AS `SafetyStockQty`,
						`tmpzh`.`ActualQty` AS `ActualQty`,
						`tmpzh`.`UniqeID` AS `UniqeID`,
						sum( `tmpzh`.`DailyQty` ) OVER ( PARTITION BY `tmpzh`.`UniqeID` ORDER BY `tmpzh`.`ProcessID`, `tmpzh`.`ScheduleDate`, `tmpzh`.`VendorID`, `tmpzh`.`Spec` ) AS `PreTotal`,
						sum( `tmpzh`.`ActualQty` ) OVER ( PARTITION BY `tmpzh`.`UniqeID` ORDER BY `tmpzh`.`ProcessID`, `tmpzh`.`ScheduleDate`, `tmpzh`.`VendorID`, `tmpzh`.`Spec` ) AS `PreOutTotal` 
					FROM
						`tmpzh` 
					),
					`tmp4` AS (
					SELECT
						`tmp3`.`ProcessID` AS `ProcessID`,
						`tmp3`.`ScheduleDate` AS `ScheduleDate`,
						`tmp3`.`VendorName` AS `VendorName`,
						`tmp3`.`MaterialName` AS `MaterialName`,
						`tmp3`.`Type` AS `Type`,
						`tmp3`.`VendorID` AS `VendorID`,
						`tmp3`.`Spec` AS `Spec`,
						`tmp3`.`WhSumQty` AS `WhSumQty`,
						`tmp3`.`SafetyStockQty` AS `SafetyStockQty`,
						`tmp3`.`DailyQty` AS `DailyQty`,
						`tmp3`.`PreTotal` AS `PreTotal`,
						`tmp3`.`RemainQty` AS `RemainQty`,
						`tmp3`.`UniqeID` AS `UniqeID`,(
						CASE
								
								WHEN ( `tmp3`.`PreTotal` <= `tmp3`.`RemainQty` ) THEN
								0 
								WHEN ((
										`tmp3`.`PreTotal` > `tmp3`.`RemainQty` 
										) 
									AND (( `tmp3`.`DailyQty` - ( `tmp3`.`PreTotal` - `tmp3`.`RemainQty` )) > 0 )) THEN
									(
									`tmp3`.`DailyQty` - ( `tmp3`.`PreTotal` - `tmp3`.`RemainQty` )) ELSE `tmp3`.`DailyQty` 
								END 
								) AS `PlanQty`,
								sum((
									CASE
											
											WHEN ( `tmp3`.`PreTotal` <= `tmp3`.`RemainQty` ) THEN
											0 
											WHEN ((
													`tmp3`.`PreTotal` > `tmp3`.`RemainQty` 
													) 
												AND (( `tmp3`.`DailyQty` - ( `tmp3`.`PreTotal` - `tmp3`.`RemainQty` )) > 0 )) THEN
												(
												`tmp3`.`DailyQty` - ( `tmp3`.`PreTotal` - `tmp3`.`RemainQty` )) ELSE `tmp3`.`DailyQty` 
											END 
											)) OVER ( PARTITION BY `tmp3`.`UniqeID` ORDER BY `tmp3`.`Type`, `tmp3`.`ProcessID`, `tmp3`.`ScheduleDate`, `tmp3`.`VendorID`, `tmp3`.`Spec` ) AS `PrePlanQty`,(
										CASE
												
												WHEN ( `tmp3`.`ActualQty` IS NULL ) THEN
												0 ELSE `tmp3`.`ActualQty` 
											END 
												) AS `ActualQty`,(
											CASE
													
													WHEN ( `tmp3`.`PreOutTotal` IS NULL ) THEN
													0 ELSE `tmp3`.`PreOutTotal` 
												END 
												) AS `PreOutTotal` 
											FROM
												`tmp3` 
											) SELECT
											`tmp4`.`VendorID` AS `VendorID`,
											`tmp4`.`ProcessID` AS `ProcessID`,
											`tmp4`.`ScheduleDate` AS `ScheduleDate`,
											`tmp4`.`VendorName` AS `VendorName`,
											`tmp4`.`MaterialName` AS `MaterialName`,
											`tmp4`.`Type` AS `Type`,
											`tmp4`.`PlanQty` AS `PlanQty`,
											`tmp4`.`ActualQty` AS `ActualQty`,
											`tmp4`.`WhSumQty` AS `WhSumQty`,
											`tmp4`.`SafetyStockQty` AS `SafetyStockQty`,
											`tmp4`.`PrePlanQty` AS `PrePlanQty`,
											`tmp4`.`PreOutTotal` AS `PreOutTotal`,(((
														`tmp4`.`WhSumQty` - `tmp4`.`SafetyStockQty` 
														) + `tmp4`.`PrePlanQty` 
													) - `tmp4`.`PreOutTotal` 
											) AS `gap`,
											`tmp4`.`UniqeID` AS `UniqeID`,
											concat( '当天库存:', `tmp4`.`WhSumQty`, ';\n安全库存:', `tmp4`.`SafetyStockQty`, ';\n累计计划入库:', `tmp4`.`PrePlanQty`, ';\n累计实际入库:', `tmp4`.`PreOutTotal` ) AS `info` 
									FROM
	`tmp4`

1.首先,这个sql长这样,嗯。。。又臭又长,优化的话我一开始还是准备从索引开始(因为这个sql太复杂了,改起来脑壳疼),先看下执行计划,查询用时6.9s。

 这个表wm_instockbill_main全表扫描了,而且有17100条,这个得优化,看sql里面有三个查询条件,这样可以加个联合索引(BillType, Status, InStockDate)。

 再看下执行计划,已经走索引了,而且过滤907,看下查询时间2.339s,嗯。。已经快了一点。

 继续优化,上面执行计划还有俩个表全表扫描了行数比较多,分别是bd_material,bd_vendor。看下sql里面,vendorid是主键,因该是会走索引的,这里失效了,难道是find_in_set导致的?换掉试下。

 改成这样

再看下执行计划,走索引了,速度也达到0.5s,还行吧。 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值