RSl*_*ter 22 sql sql-server performance
我需要编写一个查询,按年度到小时的时间段对大量记录进行分组.
我最初的方法是在C#中以程序方式决定周期,迭代每个周期并运行SQL以获取该周期的数据,随时构建数据集.
SELECT Sum(someValues)
FROM table1
WHERE deliveryDate BETWEEN @fromDate AND @ toDate
Run Code Online (Sandbox Code Playgroud)
我后来发现我可以使用Year(),Month()Day()和datepart(week,date)和datepart(hh,date)对记录进行分组.
SELECT Sum(someValues)
FROM table1
GROUP BY Year(deliveryDate), Month(deliveryDate), Day(deliveryDate)
Run Code Online (Sandbox Code Playgroud)
我担心的是,由于无法有效地使用datetime字段上的索引,因此在group by中使用datepart会导致比在一段时间内多次运行查询更糟糕的性能; 有关这是否属实的任何想法?
谢谢.
与任何与绩效相关的措施一样
检查第二种方法的查询计划将提前告诉您任何明显的问题(当您不需要时可以进行全表扫描),但无法替代测量.在SQL性能测试中,应使用适当大小的测试数据进行测量.
由于这是一个复杂的案例,您不是简单地比较两种不同的方式来执行单个查询,而是将单个查询方法与迭代方法进行比较,您的环境方面可能在实际性能中起主要作用.
特别
你可以做类似的事情:
SELECT Sum(someValues)
FROM
(
SELECT *, Year(deliveryDate) as Y, Month(deliveryDate) as M, Day(deliveryDate) as D
FROM table1
WHERE deliveryDate BETWEEN @fromDate AND @ toDate
) t
GROUP BY Y, M, D
Run Code Online (Sandbox Code Playgroud)
如果你能够容忍加入另一张桌子的表现,我有一个看似奇怪的建议,但效果很好.
创建一个我称之为ALMANAC的表,其中包含工作日,月,年等列.您甚至可以为日期的公司特定功能添加列,例如日期是否为公司假日.您可能希望添加开始和结束时间戳,如下所述.
虽然你可能每天都有一排,但是当我这样做的时候,我觉得每班一排很方便,一天有三班.即使按照这个速度,十年的时间也只有一万多排.
当您编写SQL来填充此表时,您可以使用所有面向日期的内置函数来简化工作.当您进行查询时,可以使用日期列作为连接条件,或者您可能需要两个时间戳来提供范围以捕获范围内的时间戳.其余部分与使用任何其他类型的数据一样简单.