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,还行吧。