Sql server 中Union 與 Case

 
在sql server中,我們對於一些查詢,當選擇某一個表的一部分與另一部分,或者兩個表組合成一個臨時表或者視圖時,最常用的就是Union All語句了,我的寫作水平不強,以下只是我做項目時經歷的一個真實案例。
 
如:
Select a.Name a.ID,a.Type, 1 as From from a where a.Type=’ 本站’
Union all
Select a.Name a.ID,a.Type, 2 as From from a where a.Type= ‘其它站’
 
下面以一個 2000萬數據表的建立的視圖來看看同等的Union 與Case的效率.
Union 視圖
----資源信息視圖---
-if exists (select 1
            from sysobjects
           where id = object_id('dbo.KT_V_Resources')
            and   type = 'V')
 drop view dbo.KT_V_Resources
go
Create View KT_V_Resources
As
SELECT     SiteCode, SourceID, SourceType, SourceFlag,
FromSiteCode, FromSourceID, CreateDate, ShareStatus, FromID=(Case
         When SourceFlag='2' then FromSourceID
    when SOurceFlag='0' then SourceID
end )
ROM         dbo.KT_Resources 
go
 
當把該視圖做成原子視圖,再建一個文章視圖或者其它視圖,通過該視圖與文章表,或者其它資源表聯接起來的
如:
----文章視圖----
if exists (select 1
            from sysobjects
           where id = object_id('dbo.KT_V_Articles')
            and   type = 'V')
   drop view dbo.KT_V_Articles
go
Create View KT_V_Articles
As
SELECT     dbo.KT_V_Resources.*, dbo.KT_Articles.CategID, dbo.KT_Articles.Title, dbo.KT_Articles.SubTitle, dbo.KT_Articles.Keywords,
                      dbo.KT_Articles.TItlePrix, dbo.KT_Articles.Logo, dbo.KT_Articles.Author, dbo.KT_Articles.[From], dbo.KT_Articles.Comment, dbo.KT_Articles.[Content],
                      dbo.KT_Articles.RefrenceUrl, dbo.KT_Articles.ViewCount, dbo.KT_Articles.CommentCount, dbo.KT_Articles.AutoPaging, dbo.KT_Articles.PageSize,
                      dbo.KT_Articles.Status, dbo.KT_Articles.CreateUser, dbo.KT_Articles.ModUser, dbo.KT_Articles.ModDate
FROM         dbo.KT_V_Resources INNER JOIN
                      dbo.KT_Articles ON dbo.KT_V_Resources.FromID = dbo.KT_Articles.SourceID AND dbo.KT_V_Resources.SourceType = 1
go
 
假如文章表共中有10萬條的數據,執行查詢
Select getDate();
Select * from dbo.KT_V_Articles
Select getDate();
 
時間在1分鐘左右
 
2008-04-06 12:37:19.717
…..記表
2008-04-06 12:38:10.717
51秒的時間
 
但是查詢
Select getDate();
Select * from dbo.KT_V_Resources
Select getDate();
時間差在3秒以後,這很正常.
 
有人看到以上表的結構時,可能會說是不是表結構有問題,或者說資源表,及文章表中的主鍵應該用Identity的自增字段,會不會是因爲字符串做的主鍵在數據量大時的速度很慢.
其實用Guid做主鍵,跟數字做主鍵,速度是有一點差別,但是這不是主要的。爲什麼速度這麼慢呢。
根據經驗,修改相關表的主索引,以及建立相關其它索引。這樣會不會快一點呢,經過一些修改再試,
Select getDate();
Select * from dbo.KT_V_Articles
Select getDate();
 
時間還是51秒
這是怎麼回事呢?
 
首要考慮的是索引視圖,或者精減原始視圖(資源視圖),因爲索引視圖確實會提高查詢速度.
 
一查建索引視圖的操作,要求實體字段一一對應,不用select * ,建立時加上WITH SCHEMABINDING
再試
 
Select getDate();
Select * from dbo.KT_V_Articles
Select getDate();
 
時間還是51秒
這是怎麼回事呢?
 
最後把問題點歸結到Union all 語句上,通過Case語句來代替.
if exists (select 1
            from sysobjects
           where id = object_id('dbo.KT_V_Resources')
            and   type = 'V')
   drop view dbo.KT_V_Resources
go
 
Create View  KT_V_Resources WITH SCHEMABINDING
As
SELECT     SiteCode, SourceID, SourceType, SourceFlag,
FromSiteCode, FromSourceID, CreateDate, ShareStatus, FromID=(Case
         When SourceFlag='1' then FromSourceID
    when SOurceFlag='0' then SourceID
end )
FROM dbo.KT_Resources
go
---聚集索引
CREATE UNIQUE CLUSTERED INDEX IV_KT_V_Resources_SourceID ON KT_V_Resources (SourceID)
Go
 
 
這一次再查詢10萬條數據
Select getDate();
Select * from dbo.KT_V_Articles
Select getDate();
 
時間3秒,正常
 
暈,速度快了,問題解決
 
 
總結:Union 是所有查詢速度中最慢的,需求的計算也是最多的,對於單個表或者其它用於非原子視圖或者查詢語句時,使用Union是解決問題的最簡單辦法,速度也不會有太大影響。但是做爲一些原始視圖或者大量數據查詢時,請儘量不要採用Union All ,請使用對應的Case When語句來代替。該實例來源於自己的項目中,希望給其它朋友做類似的項目時一定的幫助.
 
發佈了39 篇原創文章 · 獲贊 12 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章