我有一个我正在尝试运行的查询,运行时间很长(约1小时)并且没有产生正确的结果。我想要一些关于如何优化它的建议(我们需要每天运行几次),以及关于可能出错的一些想法。我目前的代码列在下面。
我正在尝试获取从@StartDate到当天的完整日期列表,每天迁移的数据量以及当天迁移的项目数。即使当天没有迁移,也应显示该日期。 @temp表工作正常,我可以从中选择并获得正确的结果。但是,当我添加SELECT时,它会运行一个多小时并且不会返回所需的结果。
Declare @StartDate datetime = '2015-10-01'
Declare @EndDate datetime = CAST(SYSDATETIME() as date)
declare @temp Table
(
DayDate datetime
);
WHILE @StartDate <= @EndDate
begin
INSERT INTO @temp (DayDate) VALUES (@StartDate);
SET @StartDate = Dateadd(Day,1, @StartDate);
end ;
SELECT TOP 10
CAST(t.DayDate AS date) [Date],
SUM(cr.MESSAGE_SIZE) [AmtMigrated],
COUNT(cr.MESSAGE_SIZE) [ItemsMigrated]
FROM CROSS_REFERENCE cr
RIGHT JOIN @temp t
ON t.DayDate = cr.MIGRATION_DATE_TIME
GROUP BY CAST(t.DayDate AS date)
ORDER BY CAST(t.DayDate AS date) DESC
答案 0 :(得分:1)
将您的加入条款更改为:
ON cr.MIGRATION_DATE_TIME >= t.DayDate AND cr.MIGRATION_DATE_TIME < (t.DayDate+1)
这个想法是允许仍然使用较大表上的任何索引,但要确保你在那一天考虑时间戳的范围。
将@temp
更改为常规临时表,并将DayDate
作为主键(以便将其编入索引)。
如果一个索引尚未存在,请为CROSS_REFERENCE.MIGRATION_DATE_TIME
添加索引。您可能还想查看CROSS_REFERENCE
的{{3}},以便更快地汇总这些数据。
答案 1 :(得分:0)
这样,如果你只打算进行计算,你可以创建一个materialized view,例如:
CREATE VIEW dbo.MigrationIndexedView
WITH SCHEMABINDING
AS
SELECT TOP 10
CAST(cr.MIGRATION_DATE_TIME AS date) [Date],
SUM(cr.MESSAGE_SIZE) [AmtMigrated],
COUNT(cr.MESSAGE_SIZE) [ItemsMigrated]
FROM CROSS_REFERENCE cr
GROUP BY CAST(cr.MIGRATION_DATE_TIME AS date)
ORDER BY CAST(cr.MIGRATION_DATE_TIME AS date) DESC
GO
SELECT * FROM MigrationIndexedView WHERE [Date] BETWEEN @StarDate AND @EndDate
请原谅我的拼写错误或语法,但我认为这是一个很好的开始,具体取决于您使用的SQL版本,请查看here了解更多信息