SQL 2012 查询运行了很长时间,没有产生预期的结果
SQL 2012 Query runs a long time, doesn't produce desired results
我有一个查询,我正在尝试 运行 运行 很长时间(约 1 小时),但没有产生正确的结果。我想要一些关于如何优化它的建议(我们将需要 运行 它一天几次),以及一些关于可能出错的想法。下面列出了我当前的代码。
我正在尝试获取从@StartDate 到当前日期的完整天数列表、每天迁移的数据量以及当天迁移的项目数。即使当天没有迁移任何内容,也应该显示这一天。 @temp table 有效,我可以从中 SELECT 并获得正确的结果。但是,当我按照写的那样添加 SELECT 时,它 运行 超过一个小时并且没有 return 想要的结果。
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
将您的连接子句更改为:
ON cr.MIGRATION_DATE_TIME >= t.DayDate AND cr.MIGRATION_DATE_TIME < (t.DayDate+1)
我们的想法是允许仍然使用较大 table 上的任何索引,但要确保您考虑了当天的时间戳范围。
将 @temp
更改为常规临时文件 table 并使 DayDate
成为主键(因此已编入索引)。
如果 CROSS_REFERENCE.MIGRATION_DATE_TIME
不存在索引,请添加索引。您可能还想查看 COLUMNSTORE INDEX
es for CROSS_REFERENCE
以帮助更快地聚合该数据。
这样怎么样,如果你只打算做计算,你可以创建一个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 了解更多信息
我有一个查询,我正在尝试 运行 运行 很长时间(约 1 小时),但没有产生正确的结果。我想要一些关于如何优化它的建议(我们将需要 运行 它一天几次),以及一些关于可能出错的想法。下面列出了我当前的代码。
我正在尝试获取从@StartDate 到当前日期的完整天数列表、每天迁移的数据量以及当天迁移的项目数。即使当天没有迁移任何内容,也应该显示这一天。 @temp table 有效,我可以从中 SELECT 并获得正确的结果。但是,当我按照写的那样添加 SELECT 时,它 运行 超过一个小时并且没有 return 想要的结果。
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
将您的连接子句更改为:
ON cr.MIGRATION_DATE_TIME >= t.DayDate AND cr.MIGRATION_DATE_TIME < (t.DayDate+1)
我们的想法是允许仍然使用较大 table 上的任何索引,但要确保您考虑了当天的时间戳范围。
将 @temp
更改为常规临时文件 table 并使 DayDate
成为主键(因此已编入索引)。
如果 CROSS_REFERENCE.MIGRATION_DATE_TIME
不存在索引,请添加索引。您可能还想查看 COLUMNSTORE INDEX
es for CROSS_REFERENCE
以帮助更快地聚合该数据。
这样怎么样,如果你只打算做计算,你可以创建一个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 了解更多信息