提高SQL Server表上的查询性能包含350万行并且不断增长

时间:2016-09-03 11:35:09

标签: c# sql-server database database-design query-performance

我在C#中编写了一个连接到sql server数据库快速版的应用程序,从前端我每隔几秒填充一次数据库中的特定表,并在此表中插入大约200~300行。

目前,该表包含约350万行并且其不断增长,表定义如下

[DEVICE_ID] [decimal](19, 5) NULL,
[METER_ID] [decimal](19, 5)  NULL,
[DATE_TIME] [decimal](19, 5)  NULL,
[COL1] [decimal](19, 5)  NULL,
[COL2] [decimal](19, 5)  NULL,
.
.
.
.
[COL25] [decimal](19, 5) NULL

我在Date_Time列上创建了非聚集索引,并注意到如果需要我可以创建标识列(自动增量),则不存在唯一列,但我的报告生成逻辑完全基于Date_Time列。

我通常根据时间点击查询,即。如果我需要计算月份期间col1中发生的变化。我将需要Col1的值在第一天的第一个值和月的最后一天的最后一个值,就像明智的我需要触发灵活日期的查询而我通常只需要根据Date_Time列打开任何选定的值和结束值柱。

要获取第一天col1的第一个值,查询为

select top (1) COL1 from VALUEDATA where DeviceId=@DId and MeterId =@MId and Date_Time between @StartDateTime and @EndDateTime order by Date_Time

要获取最后一天col1的最后一个值,查询为

select top (1) COL1 from VALUEDATA where DeviceId=@DId and MeterId =@MId and Date_Time between @StartDateTime and @EndDateTime order by Date_Time desc

但是当我触发上述查询大约需要20~30秒时,我相信这可以进一步优化,但不知道未来的路。

我想到的一点是创建另一个表并在每天插入第一行和最后一行并从中获取数据。但如果我能在现有的表和查询中做一些事情,我会避免相同的。

如果有人可以提供相同的输入,那将是非常值得注意的。

2 个答案:

答案 0 :(得分:1)

要完全优化这些查询,您需要两个不同的多个索引:

CREATE INDEX ix_valuedata_asc ON VALUEDATA (DeviceId, MeterId, Date_Time);
CREATE INDEX ix_valuedata_des ON VALUEDATA (DeviceId, MeterId, Date_Time DESC);

答案 1 :(得分:1)

我还有另一个建议:如果您的目标是在执行索引查找后获取COL1,COL2等的值,那么在过滤列上只有非聚集索引的解决方案仍然必须连接回主表,即;做一个bookmark / RID lookup

您的信息告诉我您的基表没有聚集的印象(没有聚集索引);实际上是heap table

如果表格上的大多数查询都遵循您描述的模式,我会创建此表clustered。与大多数人的想法相反,您不必将聚簇索引定义为(唯一)主键。如果在非唯一数据的SQL服务器中定义聚簇索引,SQL服务器将通过添加invisible row identifier ...

使其在水下'独特

如果此表上的主要(通常是 USED 选择/过滤条件)是日期时间,我会将表格更改为以下群集结构:

  1. 首先,删除所有非群集索引
  2. 然后添加以下群集索引:
  3. CREATE CLUSTERED INDEX clix_valuedata ON VALUEDATA (Date_Time, DeviceId, MeterId);

    当使用符合您的模式的查询时,如果您查看(可能!)将获得非常高效的聚集索引SEEK 样式访问您的表格查询解释计划。。现在,您将获得免费表中的所有其他列,因为不再需要书签查找。随着表格的增长,这种方法可能会更强扩展;因为SEEK的行为......