临时表上的SQL交叉联接速度较慢
已将以下代码添加到我的SQL查询中:注意缩减版本临时表上的SQL交叉联接速度较慢,sql,sql-server,join,cross-join,tempdb,Sql,Sql Server,Join,Cross Join,Tempdb,已将以下代码添加到我的SQL查询中:注意缩减版本 DECLARE @rowType AS TABLE ( rowTypeLabel NVARCHAR (20)); INSERT INTO @rowType VALUES ('Cumulative'); INSERT INTO @rowType VALUES ('Non-Cumulative'); --select * from @rowType SELECT ID,Name,StartDate, EndDate
DECLARE @rowType AS TABLE (
rowTypeLabel NVARCHAR (20));
INSERT INTO @rowType
VALUES ('Cumulative');
INSERT INTO @rowType
VALUES ('Non-Cumulative');
--select * from @rowType
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky CROSS JOIN @rowType
WHERE (rowTypeLabel = 'Cumulative'
OR (rowTypeLabel = 'Non-Cumulative'
AND (EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
运行时间从10分钟左右变为1小时左右,是否有人对原因有任何建议,没有交叉连接的结果约为46000行,之后又返回了231行,即根据查询被归类为“非累积”的任何内容。我猜这是一个非常简化的示例?所以我不能给出具体的答案,但简单的回答是,查询的累积部分比非累积部分做了更多的工作 试试这两个做比较
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky
而且
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky
WHERE EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
我预计后者需要更长的时间
此外,对于优化者来说,合并多个业务逻辑片段的条件可能非常困难。这意味着以下结构可能更有效
SELECT * FROM <non cumulative query>
UNION ALL
SELECT * FROM <cumulative query>
我猜这是一个非常简单的例子?所以我不能给出具体的答案,但简单的回答是,查询的累积部分比非累积部分做了更多的工作 试试这两个做比较
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky
而且
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky
WHERE EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
我预计后者需要更长的时间
此外,对于优化者来说,合并多个业务逻辑片段的条件可能非常困难。这意味着以下结构可能更有效
SELECT * FROM <non cumulative query>
UNION ALL
SELECT * FROM <cumulative query>
我不明白为什么这里需要交叉连接构造-这只是混淆了问题。我将该查询重写为:
SELECT ID, Name, StartDate, EndDate, 'Cumulative' AS Period
FROM dbo.sicky
UNION ALL
SELECT ID, Name, StartDate, EndDate, 'Non-Cumulative' AS Period
FROM dbo.sicky
WHERE EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
这应该是等效的,但更清楚地说明了您正在做什么。假设此联合的第一部分是您以前拥有的,第二部分是较慢的,那么很可能EndDate或实际查询中的任何等效项没有正确索引,导致过度扫描。发布您的执行计划以进行更详细的分析。我不明白您为什么需要在此处使用交叉连接构造-这只是混淆了问题。我将该查询重写为:
SELECT ID, Name, StartDate, EndDate, 'Cumulative' AS Period
FROM dbo.sicky
UNION ALL
SELECT ID, Name, StartDate, EndDate, 'Non-Cumulative' AS Period
FROM dbo.sicky
WHERE EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
这应该是等效的,但更清楚地说明了您正在做什么。假设此联合的第一部分是您以前拥有的,第二部分是较慢的,那么很可能EndDate或实际查询中的任何等效项没有正确索引,导致过度扫描。发布您的执行计划以进行更详细的分析。10分钟内完成46000行的简单选择,无需连接或子查询。。。这似乎太过分了。检查是否已在StartDate和EndDate上创建并启用索引。如果是这样,我选择mwigdahl o Dems答案。10分钟内选择46000行,进行简单选择,无需连接或子查询。。。这似乎太过分了。检查是否已在StartDate和EndDate上创建并启用索引。如果是这样,我会选择mwigdahl o Dems的答案。根据我现有的答案;我建议使用UNION ALL,这样乐观主义者甚至不会开始尝试去重复记录集。结果将是相同的,但在更短的时间内,这并没有加快处理时间,根据我现有的答案;我建议使用UNION ALL,这样乐观主义者甚至不会开始尝试去重复记录集。结果将是相同的,但在更短的时间内,这并没有加快处理时间