2013-02-21 84 views
2

我使用的是Microsoft SQL Server 2008中的SQL Server的性能,和我有這個存儲過程:提高存儲過程

ALTER PROCEDURE [dbo].[getMessagesByDates] 
     (@orderdateFirst varchar(50), 
     @orderdateLast varchar(50))  
AS 
BEGIN 
    SET NOCOUNT ON 

    SELECT TOP 100 [RecordID] 
     ,[MessageID] 
     ,[ProcessName] 
     ,[ProcessInstanceID] 
     ,[Arrival] 
     ,[MessageDateTime] 
     ,[RecvFileName] 
     ,[ArchivePath] 
     ,[SubjectID] 
     ,[SrcMessageID] 
     ,[SourceSystem] 
     ,[SourceLocation] 
     ,[MsgKey1] 
     ,[MsgKey2] 
     ,[MsgKey3] 
    FROM [Messages].[dbo].[MessagesLog] 
    WHERE 
     [Arrival] BETWEEN CONVERT(datetime, @orderdateFirst) 
        AND CONVERT(datetime, @orderdateLast) 
    ORDER BY 
     [Arrival] DESC 
END 

[到達](DateTime類型)是一個聚集唯一索引[MessagesLog ]表。 [RecordID](bigint類型)是我的聚集索引中的第二個索引鍵列。

如何提高上述過程的性能? 我正在處理數千行,需要很長時間。

+1

[不良習慣踢:選擇了錯誤的數據類型(http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/12/bad-habits-to-kick-using-the -wrong-data-type.aspx) - 你應該始終使用最合適的數據類型 - 畢竟這就是他們的存在!所以在你的情況下:將參數類型改爲'DATE'並在你的日期欄停止使用'CONVERT' - 這將顯着加快速度 – 2013-02-21 09:34:41

+1

請發佈執行計劃。如果'Arrival'是聚集索引,我期望看到一個索引seek,可以有效地返回100行。也請澄清「很多時間」是什麼。也許這個查詢遇到阻塞併發未提交的事務。 – 2013-02-21 09:42:39

回答

2

SELECT聲明之前,您的varchardatetime之間的性能改進之一是CONVERT

目前您正在對每個記錄進行2次轉換。如果你有成千上萬行會導致性能下降。

嘗試:

DECLARE @orderdateFirstDT DATETIME = CONVERT(DATETIME,@orderdateFirst) 
DECLARE @orderdateLastDT DATETIME = CONVERT(DATETIME,@orderdateLast) 

SELECT TOP 100 [RecordID] 
     .......... 
FROM [Messages].[dbo].[MessagesLog] 
WHERE [Arrival] BETWEEN @orderdateFirstDT and @orderdateLastDT 
ORDER BY [Arrival] DESC 

更妙的是將改變你的存儲過程的參數來DATETIME類型,因此這種轉換甚至不要求。但是這可能需要在此查詢範圍之外進行更改(例如,如果在調用此sproc時明確設置varchar類型參數)。

ALTER PROCEDURE [dbo].[getMessagesByDates] 
     (@orderdateFirst DATETIME, 
     @orderdateLast DATETIME)  
AS 
BEGIN 
+0

更好:使用**適當的**數據類型('DATE'或'DATETIME')並跳過所有轉換! – 2013-02-21 09:36:51

+1

@marc_s好點,我已經更新了我的答案。 – Curt 2013-02-21 09:39:21