1

我有这个结构:

WITH my_cte
    AS
    (
    SELECT y.name
    FROM 
        WHData.dbo.vw_data x
        INNER JOIN WHData.dbo.vw_DimNames y
                ON x.nameKey = y.CasinoKey
    WHERE DateKey >= CONVERT(CHAR(8),DATEADD(mm,-2,GETDATE() - DAY(GETDATE())) + 1,112)--two complete months ago    
    GROUP BY y.name
    )
SELECT *
FROM    WHAnalysis.dbo.tb_otherData a
WHERE   NOT EXISTS
                (
            SELECT 1
            FROM my_cte b
            WHERE b.name = a.name 
            );

如果我单独运行代码CTE需要 3 秒;但完整的脚本只是运行和运行。

如果我离开 aCTE并使用索引临时表,那么它会在 4 秒内运行。

我假设正在发生的是CTE正在针对每条数据记录执行,tb_otherData所以它可能需要,因为有 2000 条记录,2000 x 3sec ....太长了!

临时表解决方案很好,但出于兴趣,有没有办法更改CTE代码以使其快速运行?CTE我缺少一些技巧吗?


编辑

如果我切换到一个好的老式子查询,那么执行计划是完全一样的:

SELECT *
FROM   WHAnalysis.dbo.tb_otherData a
WHERE name not in 
        (
            SELECT y.name
            FROM 
            WHData.dbo.vw_data x
            INNER JOIN WHData.dbo.vw_DimNames y
            ON x.nameKey = y.CasinoKey
             WHERE DateKey >= CONVERT(CHAR(8),DATEADD(mm,-2,GETDATE() - DAY(GETDATE())) + 1,112)--two complete months ago   
              GROUP BY y.name
              );
4

1 回答 1

2

尝试使用此查询而不是使用 EXISTS 的子查询:

SELECT a. *
FROM    WHAnalysis.dbo.tb_otherData a
LEFT JOIN
(   SELECT y.name as name
    FROM WHData.dbo.vw_data x
         INNER JOIN WHData.dbo.vw_DimNames y
                ON x.nameKey = y.CasinoKey
         WHERE DateKey >= 
          CONVERT(CHAR(8),DATEADD(mm,-2,GETDATE() - DAY(GETDATE())) + 1,112)    
) b on a.name=b.name
WHERE b.name is null

如果DateKey从那时WHData.dbo.vw_data起它将是:

SELECT a. *
FROM    WHAnalysis.dbo.tb_otherData a
LEFT JOIN WHData.dbo.vw_DimNames y on a.name=y.name
LEFT JOIN WHData.dbo.vw_data x
   on y.CasinoKey= x.nameKey 
      and (
          x.DateKey >= 
          CONVERT(CHAR(8),DATEADD(mm,-2,GETDATE() - DAY(GETDATE())) + 1,112)
          )
WHERE x.nameKey is null
于 2013-01-31T13:17:10.587 回答