SQL Server:时间序列数据性能

pil*_*cam 7 sql-server performance sql-server-2000 time-series

我有一张超过10亿行时间序列数据的表格,具有出色的插入性能,但(有时)可怕的选择性能.

tblTrendDetails(PK如图所示排序):

PK  TrendTime    datetime
PK  CavityId     int
PK  TrendValueId int
    TrendValue   real
Run Code Online (Sandbox Code Playgroud)

该表不断提取新数据并清除旧数据,因此插入和删除性能需要保持活泼.

执行如下查询时,性能很差(30秒):

SELECT * 
FROM tblTrendDetails
WHERE TrendTime BETWEEN @inMinTime AND @inMaxTime
  AND CavityId = @inCavityId
  AND TrendValueId = @inTrendId
Run Code Online (Sandbox Code Playgroud)

如果我再次执行相同的查询(有相似的时间,但任何@inCavityId或者@inTrendId),性能非常好(1秒).性能计数器显示磁盘访问是第一次运行查询时的罪魁祸首.

有关如何在不显着影响插入或删除性能的情况下提高性能的任何建议?任何建议(包括完全更改底层数据库)都是受欢迎的.

Tim*_*ner 7

事实上,相同或类似数据的后续查询运行得更快可能是由于SQL Server 缓存了您的数据.也就是说,是否可以加快初始查询速度?

验证查询计划:

我的猜测是你的查询应该导致索引搜索而不是索引扫描(或者更糟糕的是,表扫描).请使用SET SHOWPLAN_TEXT ON;或类似功能验证此.使用between=作为您的查询确实应该利用聚集索引,尽管这是有争议的.

索引碎片:

在所有这些插入和删除之后,您的聚簇索引(在这种情况下为主键)可能会非常碎片化.我可能会检查一下DBCC SHOWCONTIG (tblTrendDetails).

您可以使用表碎片整理表的索引DBCC INDEXDEFRAG (MyDatabase, tblTrendDetails).这可能需要一些时间,但可以让表格保持可访问状态,您可以停止操作而不会产生任何令人讨厌的副作用.

您可能需要进一步使用DBCC DBREINDEX (tblTrendDetails).但这是一个脱机操作,因此只有在不需要访问表时才应执行此操作.

此处描述了一些差异:Microsoft SQL Server 2000索引碎片整理最佳实践.

请注意,您的事务日志可能会因对大型表进行碎片整理而增长很多,而且可能需要很长时间.

分区视图:

如果这些不能解决问题(或碎片不是问题),您甚至可能希望查看分区视图,在这些视图中为各种记录范围创建一组基础基表,然后在视图中将它们全部联合起来(替换原来的表格).

更好的东西:

如果这些选择的性能是真正的业务需求,您可以为更好的硬件做好准备:更快的驱动器,更多的内存等.如果您的驱动器速度是原来的两倍,那么这个查询将在一半的时间内运行,是的?此外,这对您来说可能不适用,但我只是发现更新版本的SQL Server可以更快地获得更多选项并更好地维护.我很高兴将我公司的大部分数据转移到2008R2.但我离题了......

  • +1是一个非常彻底和明确的答案.在发布问题之前,我已通过验证查询计划.但我没有考虑索引碎片.`SHOWCONTIG`肯定揭示了碎片化.我现在正在运行一个`INDEXDEFRAG`. (2认同)