我有这个结构:
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秒;但是完整的脚本只是运行并运行。
如果我离开CTE
并使用索引的临时表,则它全部以4秒运行。
我认为正在发生的是CTE
正在对tb_otherData
中的每个数据记录执行所以它可能需要,因为有2000条记录,2000 x 3秒....长!
临时表解决方案很好但是,出于兴趣,有没有办法更改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
);
答案 0 :(得分: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