【问题标题】:SQL Server : time-series data performanceSQL Server:时间序列数据性能
【发布时间】:2023-04-08 11:16:01
【问题描述】:

我有一个包含超过 10 亿行时间序列数据的表,具有出色的插入性能,但(有时)选择性能很差。

tblTrendDetails(PK排序如图):

PK  TrendTime    datetime
PK  CavityId     int
PK  TrendValueId int
    TrendValue   real

该表不断地拉入新数据并清除旧数据,因此插入和删除性能需要保持敏捷。

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

SELECT * 
FROM tblTrendDetails
WHERE TrendTime BETWEEN @inMinTime AND @inMaxTime
  AND CavityId = @inCavityId
  AND TrendValueId = @inTrendId

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

关于如何在不(显着)对插入或删除性能产生不利影响的情况下提高性能的任何建议?欢迎提出任何建议(包括完全更改底层数据库)。

【问题讨论】:

  • PK是否集群?有索引吗?
  • @TimLehner 是的.. PK 是集群的。没有(其他)索引。

标签: sql-server performance sql-server-2000 time-series


【解决方案1】:

相同或相似数据的后续查询运行速度更快的事实可能是由于 SQL Server caching your data。也就是说,是否可以加快这个初始查询的速度?

验证查询计划:

我的猜测是您的查询应该导致索引搜索而不是索引扫描(或更糟的是,表扫描)。请使用SET SHOWPLAN_TEXT ON; 或类似功能验证这一点。使用between= 作为您的查询确实应该take advantage of the clustered index,尽管that's debatable

索引碎片化:

在所有这些插入和删除操作之后,您的聚集索引(在本例中为主键)可能非常碎片化。我可能会用DBCC SHOWCONTIG (tblTrendDetails) 来检查这个。

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

您可能需要进一步使用DBCC DBREINDEX (tblTrendDetails)。不过,这是一个离线操作,因此您应该只在不需要访问表时才执行此操作。

此处描述了一些差异:Microsoft SQL Server 2000 Index Defragmentation Best Practices

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

分区视图:

如果这些都不能解决问题(或者碎片不是问题),您甚至可能希望查看partitioned views,您可以在其中为各种记录范围创建一堆基础基表,然后将它们全部合并在视图中(替换原来的表格)。

更好的东西:

如果这些选择的性能是真正的业务需求,您也许可以为更好的硬件提供理由:更快的驱动器、更多的内存等。如果您的驱动器速度是原来的两倍,那么此查询将运行一半时间,是吗?此外,这可能对您不适用,但我只是发现较新版本的 SQL Server 确实更快,具有更多选项并且更好地维护。我很高兴将公司的大部分数据移至 2008R2。但我离题了...

【讨论】:

  • +1 以获得非常彻底和明确的答案。在发布问题之前,我已经验证了查询计划。但是我没有考虑索引碎片。 SHOWCONTIG 肯定揭示了碎片化。我现在正在运行INDEXDEFRAG
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-22
  • 2015-09-04
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多