Sql-server – Understanding Execution Plan

execution-plansql server

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 

enter image description here

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 

enter image description here

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.