I am really having hard time understanding the below execution plan.
Query 1: (Simple Select Query)
Record count of ##SALES_UNIT_RESULT
is 168. In first execution plan it is fine.
;WITH MONTHLY_PER_BUSINESS
AS (SELECT ITEM_MASTER_SID,
P.PERIOD_SID,
Q_PERIOD_SID = Min(P.PERIOD_SID)
OVER(
PARTITION BY ITEM_MASTER_SID, P.YEAR, P.QUARTER),
ACT_MONTHLY_PER_BUSINESS=FORECAST_GTS_SALES / Sum(FORECAST_GTS_SALES)
OVER(
PARTITION BY ITEM_MASTER_SID, P.[QUARTER], P.[YEAR]),
FORE_MONTHLY_PER_BUSINESS=ACTUAL_GTS_SALES / Sum(ACTUAL_GTS_SALES)
OVER(
PARTITION BY ITEM_MASTER_SID, P.[QUARTER], P.[YEAR]),
CALC_WAC_PRICE
FROM ##GTS_WAC GW
INNER JOIN PERIOD P
ON GW.PERIOD_SID = P.PERIOD_SID)
SELECT SR.PROJECTION_DETAILS_SID,
PROJECTED_SALES = CASE
WHEN BASED_ON = 'SALES' THEN SR.PROJECTED_SALES_UNITS * COALESCE(MPB.FORE_MONTHLY_PER_BUSINESS, MPB.ACT_MONTHLY_PER_BUSINESS)
ELSE PROJECTED_SALES_UNITS * COALESCE(MPB.FORE_MONTHLY_PER_BUSINESS, MPB.ACT_MONTHLY_PER_BUSINESS) * CALC_WAC_PRICE
END,
PROJECTED_UNITS = CASE
WHEN BASED_ON = 'SALES' THEN ( SR.PROJECTED_SALES_UNITS * COALESCE(MPB.FORE_MONTHLY_PER_BUSINESS, MPB.ACT_MONTHLY_PER_BUSINESS) ) / NULLIF(CALC_WAC_PRICE, 0)
ELSE PROJECTED_SALES_UNITS * COALESCE(MPB.FORE_MONTHLY_PER_BUSINESS, MPB.ACT_MONTHLY_PER_BUSINESS)
END,
MPB.PERIOD_SID
FROM MONTHLY_PER_BUSINESS MPB
INNER JOIN ##SALES_UNIT_RESULT SR
ON SR.ITEM_MASTER_SID = MPB.ITEM_MASTER_SID
AND SR.PERIOD_SID = MPB.Q_PERIOD_SID
Query 2:(Update query with same above Select query)
Here if you see the from ##SALES_UNIT_RESULT
table 169344
are coming out for next step.Why when Update is introduced 168
records are increased to 169344
. Can anyone tell me what's going on?
;WITH MONTHLY_PER_BUSINESS
AS (SELECT ITEM_MASTER_SID,
P.PERIOD_SID,
Q_PERIOD_SID = Min(P.PERIOD_SID)
OVER(
PARTITION BY ITEM_MASTER_SID, P.YEAR, P.QUARTER),
ACT_MONTHLY_PER_BUSINESS=FORECAST_GTS_SALES / Sum(FORECAST_GTS_SALES)
OVER(
PARTITION BY ITEM_MASTER_SID, P.[QUARTER], P.[YEAR]),
FORE_MONTHLY_PER_BUSINESS=ACTUAL_GTS_SALES / Sum(ACTUAL_GTS_SALES)
OVER(
PARTITION BY ITEM_MASTER_SID, P.[QUARTER], P.[YEAR]),
CALC_WAC_PRICE
FROM ##GTS_WAC GW
INNER JOIN PERIOD P
ON GW.PERIOD_SID = P.PERIOD_SID)
UPDATE NSP
SET NSP.PROJECTION_SALES = A.PROJECTED_SALES,
NSP.PROJECTION_UNITS = A.PROJECTED_UNITS
FROM ST_NM_SALES_PROJECTION NSP
INNER JOIN (SELECT SR.PROJECTION_DETAILS_SID,
PROJECTED_SALES = CASE
WHEN BASED_ON = 'SALES' THEN SR.PROJECTED_SALES_UNITS * COALESCE(MPB.FORE_MONTHLY_PER_BUSINESS, MPB.ACT_MONTHLY_PER_BUSINESS)
ELSE PROJECTED_SALES_UNITS * COALESCE(MPB.FORE_MONTHLY_PER_BUSINESS, MPB.ACT_MONTHLY_PER_BUSINESS) * CALC_WAC_PRICE
END,
PROJECTED_UNITS = CASE
WHEN BASED_ON = 'SALES' THEN ( SR.PROJECTED_SALES_UNITS * COALESCE(MPB.FORE_MONTHLY_PER_BUSINESS, MPB.ACT_MONTHLY_PER_BUSINESS) ) / NULLIF(CALC_WAC_PRICE, 0)
ELSE PROJECTED_SALES_UNITS * COALESCE(MPB.FORE_MONTHLY_PER_BUSINESS, MPB.ACT_MONTHLY_PER_BUSINESS)
END,
MPB.PERIOD_SID
FROM MONTHLY_PER_BUSINESS MPB
INNER JOIN ##SALES_UNIT_RESULT SR
ON SR.ITEM_MASTER_SID = MPB.ITEM_MASTER_SID
AND SR.PERIOD_SID = MPB.Q_PERIOD_SID) A
ON NSP.PROJECTION_DETAILS_SID = A.PROJECTION_DETAILS_SID
AND NSP.PERIOD_SID = A.PERIOD_SID
WHERE [USER_ID] = 12
AND SESSION_ID = 12
Best Answer
The count is not distinct rows - so if the table is scanned many times each row will be counted many time. In this case the nested loops join with the scan is reading all 168 rows once for each of the 1008 rows coming out of the other leg which explains the 169344.
I'm guessing that none of the temporary tables have any indexes which would explain the planner resorting to multiple scans, so creating appropriate ones could make a massive difference to the resulting query plans.