2014-12-08 83 views
0

我有一個關於性能的問題,目前我有一個表在查詢性能方面遇到麻煩,只要表中的行已經有數百萬條記錄。SQL Server 2014標準版大表性能

這是表:

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 

它與HistoryParameterIDSourceTimeStamp聚集索引相當平坦。

這是我使用

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) 

正如你可以看到HistoryParameterIDSourceTimestamp被用作第一查詢參數的存儲過程。並檢索8小時的記錄,這是約28千記錄,它返回與不穩定的表現,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 <[email protected]) 
     AND (@ValueStatus = -1 OR ValueStatus = @ValueStatus) 

我在檢索41213列在表中的〜849600000行得到了1.396秒客戶端的處理時間。

有沒有辦法改善這一點?

+2

好奇知道爲什麼動態查詢? – Anil 2014-12-08 08:25:54

+0

基於測試,我可以使用動態查詢來提高性能,與其他人相比 – carlcrol 2014-12-08 08:28:42

+0

如果您打算重用查詢,參數將爲您提供更好的結果。 – 2014-12-08 08:31:04

回答

0

每次執行新的SQL命令時,都必須由MS SQL Server編譯。如果您重新使用該命令,則可節省編譯時間。你需要直接在存儲過程中執行這個命令,這樣可以編譯並給出更一致的結果。

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

這會給你一個機會來監視命令的執行。

+0

好的,謝謝奧利弗。會嘗試一下。 – carlcrol 2014-12-09 00:35:55

+0

順便說一句,你有任何想法是什麼性能SQL Server的查詢條款?它是否可以處理標準版會遇到的場景而無需分開? – carlcrol 2014-12-09 00:36:49

+0

嗨奧利弗,試過你的建議,我試着用2個應用程序在同一時間檢索〜28K記錄。我平均有2秒的時間,這很慢。 – carlcrol 2014-12-09 05:06:16