朋友提出的一個字段更新問題。
問題:Sqlserver中ConfigMgr中有一張表為Person,有一個字段為sex char(4),保存性別(‘男’或‘女’),該表中有多條記錄,如何用一條語句實現將‘男’改為‘女’,‘女’改為‘男’?
測試目標數據庫版本為:Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)
首先向Person表插入10萬條,腳本如下:
set @i = 0
while @i < 10000
begin
if @i % 2 = 1
insert into [ ConfigMgr ]. [ dbo ]. [ Person ]
values( ' 男 ')
else
insert into [ ConfigMgr ]. [ dbo ]. [ Person ]
values( ' 女 ')
set @i = @i + 1
end
我的解決方法如下:
語句1:
set @d = GETDATE()
update [ ConfigMgr ]. [ dbo ]. [ Person ]
set Sex =
case
when Sex = ' 男 ' then ' 女 '
when Sex = ' 女 ' then ' 男 '
end
select Elapsed_MillionSecond = DATEDIFF(ms, @d, getdate())
語句2:
set @d = GETDATE()
update t1
set t1.sex =t2.sex
from [ ConfigMgr ]. [ dbo ]. [ Person ] as t1, [ ConfigMgr ]. [ dbo ]. [ Person ] as t2
where t1.Sex !=t2.Sex
select Elapsed_MillionSecond = DATEDIFF(ms, @d, getdate())
性能分析:
首先執行set statistics profile on 來查看語句的具體執行過程,同時選中查看執行計划和客戶端統計信息,可以看到語句1和語句2的執行的相關信息。
當Person表中數據量10萬條時,兩種方法的差別不是太大,當表中數據量增大到100萬時,兩種方法的性別差異就比較大了,對比可知語句1的執行效率明顯要高於語句2,對比截圖如下所示:
Person中表數據量10萬條時:
語句1的執行10次的客戶端統計信息如下圖所示:
語句1的執行計划圖如下所示:
語句1的具體執行過程如下圖所示:
語句2的執行10次的客戶端統計信息如下圖所示:
語句2的執行計划圖如下所示:
語句2的具體執行過程如下圖所示:
通過對比語句1與語句2的客戶端統計圖可以看到兩語句分別所耗時間及執行過程的具體操作步驟,在10條時,語句1操作10次平均耗時為:368.4毫秒,而語句2平均耗時為:808.7毫秒,兩者相關約一倍時間。
下面看一下當Person表中數據量為100萬時,語句1與語句2的執行10次的客戶端統計情況對比對比,執行過程與10萬條時是相同的,只是數據量大小不一樣了。
語句1的執行10次的客戶端統計信息如下圖所示:
語句2的執行10次的客戶端統計信息如下圖所示:
通過上圖的對比,可以很清楚的看到語句1的執行時間相比語句2要縮短約4倍,數據量越大時,兩者的性能差異也就越大。語句1的性能要優於語句2。
另:如果是在oracle中,用decode函數可以輕松解決。