在查詢優化器生成執行計劃過程中,需要參考中繼資料來盡可能生成高效的執行計劃,是以中繼資料越多,則執行計劃更可能會高效。所謂需要參考的中繼資料主要包括:索引、表結構、統計資訊等,但還有一些不是很被注意的中繼資料,其中包括本文闡述的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,如需轉載請自行聯系原作者