0

我有一个关于性能的问题,目前我有一个表,只要表行已经有数百万条记录,查询性能就会出现问题。

这是表格:

CREATE TABLE [dbo].[HistorySampleValues]
(
    [HistoryParameterID] [int] NOT NULL,
    [SourceTimeStamp] [datetime2](7) NOT NULL,
    [ArchiveTimestamp] [datetime2](7) NOT NULL CONSTRAINT [DF__HistorySa__Archi__2A164134]  DEFAULT (getutcdate()),
    [ValueStatus] [int] NOT NULL,
    [ArchiveStatus] [int] NOT NULL,
    [IntegerValue] [bigint] SPARSE  NULL,
    [DoubleValue] [float] SPARSE  NULL,
    [StringValue] [varchar](100) SPARSE  NULL,
    [EnumNamedSetName] [varchar](100) SPARSE  NULL,
    [EnumNumericValue] [int] SPARSE  NULL,
    [EnumTextualValue] [varchar](256) SPARSE  NULL
) ON [PRIMARY]

CREATE CLUSTERED INDEX [Source_HistParameterID_Index] ON [dbo].[HistorySampleValues]
(
    [HistoryParameterID] ASC,
    [SourceTimeStamp] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO

HistoryParameterID它在和上有一个聚集索引相当平坦SourceTimeStamp

这是我正在使用的存储过程

   SET NOCOUNT ON;
   DECLARE @SqlCommand NVARCHAR(MAX)

   SET @SqlCommand = 'SELECT HistoryParameterID, 
                            SourceTimestamp, ArchiveTimestamp,ValueStatus,ArchiveStatus,
                            IntegerValue,DoubleValue,StringValue,EnumNumericValue,
                            EnumTextualValue,EnumNamedSetName 
                        FROM [HistorySampleValues] WITH(NOLOCK) 
                        WHERE ([HistoryParameterID] =' + @ParamIds + '
                        AND
                        [SourceTimeStamp] >= ''' + CONVERT(VARCHAR(30),@StartTime, 25) + '''
    AND           
    [SourceTimeStamp] <= ''' + CONVERT(VARCHAR(30),@EndTime, 25) + ''') 
    AND ValueStatus = ' + @ValueStatus 

    EXECUTE( @SqlCommand )

如您所见,HistoryParameterIDandSourceTimestamp被用作第一个查询的参数。并检索价值 8 小时的记录,即约 28k 记录,它以不稳定的性能返回,1.8 秒 - 700 毫秒

设计会规模化吗?何时达到 770 亿条记录?或者有什么策略可以使用?SQL Server 的版本是标准版,因此没有要使用的分区和列存储。或者我是否达到了 SQL Server 标准版的最大性能?


这是更新的存储过程

 @ParamIds int,
    @StartTime datetime,
    @EndTime datetime,
    @ValueStatus int 
AS
BEGIN
       SET NOCOUNT ON;
       SELECT HistoryParameterID, 
        SourceTimestamp, ArchiveTimestamp,ValueStatus,ArchiveStatus,
        IntegerValue,DoubleValue,StringValue,EnumNumericValue,
        EnumTextualValue,EnumNamedSetName 
        FROM [HistorySampleValues] WITH(NOLOCK) 
        WHERE 
        HistoryParameterID = @ParamIds
        AND (SourceTimeStamp >= @StartTime AND SourceTimeStamp <=@EndTime)
        AND (@ValueStatus = -1 OR ValueStatus = @ValueStatus)

在将 41213 行检索到表中的 ~849600000 行时,我得到了 1.396 秒的客户端处理时间。

有没有办法改善这一点?

4

1 回答 1

0

每次执行新的 SQL 命令时,都必须由 MS SQL Server 编译。如果您重复使用该命令,则可以节省编译时间。您需要像这样在存储过程中直接执行命令,这应该允许编译并为您提供更一致的结果。

SELECT ... 
WHERE ([HistoryParameterID] = @ParamIds 
AND [SourceTimeStamp] >= @StartTime
AND [SourceTimeStamp] <= @EndTime 
AND ValueStatus = @ValueStatus 

这也将使您有机会监视命令的性能。

于 2014-12-08T08:59:56.183 回答