【发布时间】:2016-04-22 21:43:19
【问题描述】:
我正在设法减少执行此查询所需的时间。现在,根据服务器的不同,它需要 30-90 分钟。我仍在学习索引,因此这是未来项目的一个选项,我也在寻找可能有助于优化查询本身的建议。数据库非常大,在主表中包含 10-1 亿行。任何的意见都将会有帮助!
(我已将列名更改为对这篇文章更具描述性)
USE MyDB
DECLARE @interval int = 6
DECLARE @mindate DATETIME = (SELECT DATEADD(HOUR, DATEDIFF(HOUR,0,MIN(DateColumn))/@interval*@interval, 0) FROM MyTable1)
DECLARE @maxdate DATETIME = (SELECT DATEADD(HOUR, DATEDIFF(HOUR,0,MAX(DateColumn))/@interval*@interval, 0) FROM MyTable1)
DECLARE @end DATETIME = (SELECT DATEADD(HOUR, DATEDIFF(HOUR,0,GETDATE())/@interval*@interval, 0))
--=========================================================
-- Update all DATEADD statements to desired interval
--=========================================================
;WITH cte
AS (SELECT
[StartTime] = CONVERT(datetime,@mindate),
[EndTime] = DATEADD(HOUR, @interval, CONVERT(datetime,@mindate))
UNION ALL
SELECT
DATEADD(HOUR, @interval, [StartTime]),
DATEADD(HOUR, @interval, [EndTime])
FROM cte
WHERE [EndTime] < @end)
--==========================================================
SELECT
[ServerName] = ServerName,
[StartTime] = CONVERT(varchar, [StartTime], 121),
[EndTime] = CONVERT(varchar, [EndTime], 121),
[ItemsMigrated] = COUNT(ItemIDColumn),
[SizeMigrated] = ISNULL(SUM(ItemSizeColumn),0),
[ItemsFailed] = (SELECT COUNT(*) FROM MyTable2 WHERE ItemStatusColumn = "Failed")
FROM cte
LEFT JOIN MyTable1 cr ON cr.DateColumn >= [StartTime] AND cr.DateColumn < [EndTime]
GROUP BY cte.StartTime, cte.EndTime
ORDER BY cte.StartTime
OPTION (MAXRECURSION 0)
【问题讨论】:
-
你检查执行计划了吗?到目前为止,您创建了哪些索引?
-
尝试将 cte 实现为 #temp
-
这太疯狂了 "[ItemsFailed] = (SELECT COUNT(*) FROM MyTable2 WHERE ItemStatusColumn = "Failed")" 为什么不只计算一次呢?
-
您可能需要查看here 以获取有关提高 CTE 性能的提示。您的查询的典型日期范围是什么?
-
你能给出一份需求清单——你到底想做什么?看起来您正在做很多可以简单完成的事情,但它太迟钝了,我不确定目标是什么。例如——您要四舍五入到最接近的 6 小时标记?然后得到最小值和最大值?
标签: sql-server tsql indexing query-optimization