CTE занимает вечность, чтобы выполнить запрос сравнения с временной таблицей в SQL Server

#sql-server #tsql #common-table-expression

#sql-server #tsql #common-table-expression

Вопрос:

Я хочу оптимизировать CTE в SQL Server. CTE занимает так много времени, чтобы выполнить запрос. Однако, когда я использую временную таблицу вместо CTE, выполнение CTE происходит быстро. Это из-за многократного присоединения к CTE в конечном запросе?

Код CTE выглядит следующим образом:

 WITH Aggregates
AS (SELECT Survey_Nm,
           Brand_Nm,
           Dealer_Nm,
           Market_Nm,
           Region_Nm,
           SUM(Base_Points) / NULLIF(SUM(Questions_Answered), 0) AS Initial_Score,
           (SUM(ExtraCredit_Points) * 1.0 / COUNT(DISTINCT Response_Id)) / 100 AS ExtraCredit_Perc,
           (SUM(Base_Points) / NULLIF(SUM(Questions_Answered), 0))
             ((SUM(ExtraCredit_Points) * 1.0 / COUNT(DISTINCT Response_Id)) / 100) AS Score
    FROM dbo.vw_RPTS_SurveyResponses
    GROUP BY GROUPING SETS((Market_Nm), (Region_Nm), (), (Survey_Nm, Brand_Nm, Dealer_Nm, Market_Nm, Region_Nm)))
SELECT SR.Survey_Nm,
       SR.Brand_Nm,
       SR.Dealer_Nm,
       SR.Market_Nm,
       SR.Region_Nm,
       SR.Initial_Score AS Initial_Dealer_Score,
       SR.ExtraCredit_Perc AS DealerExtraCredit_Perc,
       SR.Score AS Dealer_Score,
       M.Initial_Score AS Initial_Market_Score,
       M.ExtraCredit_Perc AS Market_ExtraCredit_Perc,
       M.Score AS Market_Score,
       R.Initial_Score AS Initial_Region_Score,
       R.ExtraCredit_Perc AS Region_ExtraCredit_Perc,
       R.Score AS Region_Score,
       N.Initial_Score AS Initial_National_Score,
       N.ExtraCredit_Perc AS Nation_ExtraCredit_Perc,
       N.Score AS National_Score
FROM Aggregates AS SR
    INNER JOIN Aggregates AS M
        ON M.Market_Nm = SR.Market_Nm
           AND M.Survey_Nm IS NULL
           AND M.Brand_Nm IS NULL
           AND M.Dealer_Nm IS NULL
           AND M.Region_Nm IS NULL
           AND M.Market_Nm IS NOT NULL
    INNER JOIN Aggregates AS R
        ON R.Region_Nm = SR.Region_Nm
           AND R.Survey_Nm IS NULL
           AND R.Brand_Nm IS NULL
           AND R.Dealer_Nm IS NULL
           AND R.Region_Nm IS NOT NULL
           AND R.Market_Nm IS NULL
    INNER JOIN Aggregates AS N
        ON 1 = 1
           AND N.Survey_Nm IS NULL
           AND N.Brand_Nm IS NULL
           AND N.Dealer_Nm IS NULL
           AND N.Region_Nm IS NULL
           AND N.Market_Nm IS NULL
WHERE SR.Survey_Nm IS NOT NULL
      AND SR.Brand_Nm IS NOT NULL
      AND SR.Dealer_Nm IS NOT NULL
      AND SR.Market_Nm IS NOT NULL
      AND SR.Region_Nm IS NOT NULL;
  

Комментарии:

1. поскольку вы ссылаетесь на CTE Aggregates 4 раза, поэтому CTE необходимо оценить 4 раза. В результате перенос данных во временную таблицу будет намного быстрее. Однако, вероятно, вам не нужно ссылаться на представление vw_RPTS_SurveyResponses 4 раза, и вы можете сделать это за один проход; если мы знаем, какова ваша реальная цель. Эти ON предложения также выглядят очень странно.

2. @Larnu, в общем, моя реальная цель — объединить данные по 4 измерениям ((Market_Nm), (Region_Nm), (), (Survey_Nm, Brand_Nm, Dealer_Nm, Market_Nm, Region_Nm)) vw_RPTS_SurveyResponses и объединить все измерения на основе (Survey_Nm, Brand_Nm, Dealer_Nm, Market_Nm, Region_Nm) измерения.

3. Если у вас есть inner join on R.Region_Nm = SR.Region_Nm and ... followed by where ... and SR.Region_Nm IS NOT NULL; , оптимизатор запросов может от чего-то избавиться. Аналогично для SR.Market_Nm . И cross join с N тех пор 1 = 1 , как часто верно? Фактический план выполнения часто является местом, с которого начинаются проблемы с производительностью. Пожалуйста, смотрите раздел Вставить план , чтобы узнать, как включить план выполнения в ваш вопрос.