天天看點

SQL Server中使用Check限制提升性能

    在查詢優化器生成執行計劃過程中,需要參考中繼資料來盡可能生成高效的執行計劃,是以中繼資料越多,則執行計劃更可能會高效。所謂需要參考的中繼資料主要包括:索引、表結構、統計資訊等,但還有一些不是很被注意的中繼資料,其中包括本文闡述的Check限制。

    查詢優化器在生成執行計劃之前有一個階段叫做代數樹優化,比如說下面這個簡單查詢:

    image

    圖1.簡單查詢

    查詢優化器意識到1=2這個條件是永遠不相等的,是以不需要傳回任何資料,是以也就沒有必要掃描表,從圖1執行計劃可以看出僅僅掃描常量後确定了1=2永遠為false後,就可完成查詢。

那麼Check限制呢

    Check限制可以確定一列或多列的值符合表達式的限制。在某些時候,Check限制也可以為優化器提供資訊,進而優化性能,比如看圖二的例子。

image

圖2.有Check限制的列提升查詢性能

    圖2是一個簡單的例子,有時候在分區視圖中應用Check限制也會提升性能,測試代碼如下:

CREATE TABLE [dbo].[Test2007](

    [ProductReviewID] [int] IDENTITY(1,1) NOT NULL,

    [ReviewDate] [datetime] NOT NULL

) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Test2007]  WITH CHECK ADD  CONSTRAINT [CK_Test2007] CHECK  (([ReviewDate]>='2007-01-01' AND [ReviewDate]<='2007-12-31'))

ALTER TABLE [dbo].[Test2007] CHECK CONSTRAINT [CK_Test2007]

CREATE TABLE [dbo].[Test2008](

ALTER TABLE [dbo].[Test2008]  WITH CHECK ADD  CONSTRAINT [CK_Test2008] CHECK  (([ReviewDate]>='2008-01-01' AND [ProductReviewID]<='2008-12-31'))

ALTER TABLE [dbo].[Test2008] CHECK CONSTRAINT [CK_Test2008]

INSERT INTO [Test2008] values('2008-05-06')

INSERT INTO [Test2007] VALUES('2007-05-06')

CREATE VIEW testPartitionView

AS

SELECT * FROM Test2007

UNION

SELECT * FROM Test2008

SELECT * FROM testPartitionView

WHERE [ReviewDate]='2007-01-01'

WHERE [ReviewDate]='2008-01-01'

WHERE [ReviewDate]='2010-01-01'

代碼清單1.

    我們針對Test2007和Test2008兩張表結構一模一樣的表做了一個分區視圖。并對日期列做了Check限制,限制每張表包含的資料都是特定一年内的資料。當我們對視圖進行查詢并給定不同的篩選條件時,可以看到結果如圖3所示。

圖3.不同的條件産生不同的執行計劃

    由圖3可以看出,當篩選條件為2007年時,自動隻掃描2007年的表,2008年的表也是同樣。而當查詢範圍超出了2007和2008年的Check限制後,查詢優化器自動判定結果為空,是以不做任何IO操作,進而提升了性能。

結論

    在Check限制條件為簡單的情況下(指的是限制限制在單列且表達式中不包含函數),不僅可以限制資料完整性,在很多時候還能夠提供給查詢優化器資訊進而提升性能。

分類: SQL性能調優

本文轉自CareySon部落格園部落格,原文連結http://www.cnblogs.com/CareySon/p/UsingCheckBoostPerformance.html,如需轉載請自行聯系原作者