SQL Server中使用Check約束提升性能


    在SQL Server中,SQL語句的執行是依賴查詢優化器生成的執行計划,而執行計划的好壞直接關乎執行性能。

    在查詢優化器生成執行計划過程中,需要參考元數據來盡可能生成高效的執行計划,因此元數據越多,則執行計划更可能會高效。所謂需要參考的元數據主要包括:索引、表結構、統計信息等,但還有一些不是很被注意的元數據,其中包括本文闡述的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'))
GO
 
ALTER TABLE [dbo].[Test2007] CHECK CONSTRAINT [CK_Test2007]
GO
 
 
CREATE TABLE [dbo].[Test2008](
    [ProductReviewID] [int] IDENTITY(1,1) NOT NULL,
    [ReviewDate] [datetime] NOT NULL
) ON [PRIMARY]
 
GO
 
ALTER TABLE [dbo].[Test2008]  WITH CHECK ADD  CONSTRAINT [CK_Test2008] CHECK  (([ReviewDate]>='2008-01-01' AND [ProductReviewID]<='2008-12-31'))
GO
 
ALTER TABLE [dbo].[Test2008] CHECK CONSTRAINT [CK_Test2008]
GO
 
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'
 
 
SELECT * FROM testPartitionView
WHERE [ReviewDate]='2008-01-01'
 
 
SELECT * FROM testPartitionView
WHERE [ReviewDate]='2010-01-01'

代碼清單1.

 

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

image

圖3.不同的條件產生不同的執行計划

 

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

 

結論

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM