在sql server中,sql語句的執行是依賴查詢優化器生成的執行計畫,而執行計畫的好壞直接關乎執行效能。
在查詢優化器生成執行計畫過程中,需要參考元資料來盡可能生成高效的執行計畫,因此元資料越多,則執行計畫更可能會高效。所謂需要參考的元資料主要包括:索引、表結構、統計資訊等,但還有一些不是很被注意的元資料,其中包括本文闡述的check約束。
查詢優化器在生成執行計畫之前有乙個階段叫做代數樹優化,比如說下面這個簡單查詢:
圖1.簡單查詢
查詢優化器意識到1=2這個條件是永遠不相等的,因此不需要返回任何資料,因此也就沒有必要掃瞄表,從圖1執行計畫可以看出僅僅掃瞄常量後確定了1=2永遠為false後,就可完成查詢。
那麼check約束呢
check約束可以確保一列或多列的值符合表示式的約束。在某些時候,check約束也可以為優化器提供資訊,從而優化效能,比如看圖二的例子。
圖2.有check約束的列提公升查詢效能
圖2是乙個簡單的例子,有時候在分割槽檢視中應用check約束也會提公升效能,測試**如下:
createtable [dbo].[test2007](
[productreviewid] [int] identity(1,1) notnull,
[reviewdate] [datetime] notnull
) on [primary]
go
altertable [dbo].[test2007] with
check
addconstraint [ck_test2007] check (([reviewdate]>='2007-01-01'
and [reviewdate]<='2007-12-31'))
go
altertable [dbo].[test2007] check
constraint [ck_test2007]
go
createtable [dbo].[test2008](
[productreviewid] [int] identity(1,1) notnull,
[reviewdate] [datetime] notnull
) on [primary]
go
altertable [dbo].[test2008] with
check
addconstraint [ck_test2008] check (([reviewdate]>='2008-01-01'
and [productreviewid]<='2008-12-31'))
go
altertable [dbo].[test2008] check
constraint [ck_test2008]
go
insert into [test2008] values('2008-05-06')
insert into [test2007] values('2007-05-06')
createview 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所示。
圖3.不同的條件產生不同的執行計畫
由圖3可以看出,當篩選條件為2023年時,自動只掃瞄2023年的表,2023年的表也是同樣。而當查詢範圍超出了2007和2023年的check約束後,查詢優化器自動判定結果為空,因此不做任何io操作,從而提公升了效能。
結論
在check約束條件為簡單的情況下(指的是約束限制在單列且表示式中不包含函式),不僅可以約束資料完整性,在很多時候還能夠提供給查詢優化器資訊從而提公升效能。
在SQL Server中使用索引的技巧
在sql server中,為了查詢效能的優化,有時我們就需要對資料表通過建立索引的方式,目的主要是根據查詢要求,迅速縮小查詢範圍,避免全表掃瞄。索引有兩種型別,分別是聚集索引 clustered index,也稱聚類索引 簇集索引 和非聚集索引 nonclustered index,也稱非聚類索引 ...
原 SQL Server中使用CTE遞迴查詢
目錄 背景 問題思路 ctecte遞迴查詢 結束語參考資料 怎麼遍歷出乙個父級選單下所有子選單?思路 定義語法結構 使用cte準則 示例 定義 cte common table expressions 是從sql server 2005以後版本才有的。指定的臨時命名結果集,這些結果集稱為cte。與派...
SQL Server 2000 中使用正規表示式
這兩天有個需求,需要在資料庫中判斷字串的格式,於是從網上蒐集了一些資料,整理了一下。下面這個是乙個自定義函式,使用者可以呼叫這個函式判斷指定的字串是否符合正規表示式的規則.create function dbo.find regular expression source varchar 5000 ...