Sql Server中三种字符串合并方法的性能比较
?最近正在處理一個合并字符呂的存儲過程,在一個測試系統的開發中,要使用到字符串合并功能,直接在Sql中做。
????????示例:
????????有表內容﹕
????????名稱??內容
?????????1?????abc
????????1??????aaa
????????1??????dddd
????????2??????1223
????????2???????fkdjfd
???????????--------------------------------
????????結果﹕
????????1???abc,aaa,dddd
????????2???1223,fkdjfd
????????要求用一條SQL語句實現﹐如﹕select?sum(內容)?from?table?group?by?名稱
????????--該問題,一共使用了三種方法,并分別測試了一下這三種方法的各自的性能
????????1:?創建處理函數
????????2?:??sql?2005及以上版本中的新的解決方法,FOR?XML
????????3?:??使用臨時表實現字符串合并處理的示例
說明:以下測試是以本人機器的硬件配置為準,根據硬件配置的不同,結果可能不同。
1:?創建處理函數
???????說明:sql?全系列版本
CREATE?FUNCTION?dbo.f_strHeBin(@id?int)
RETURNS?varchar(8000)
AS
BEGIN
????DECLARE?@r?varchar(8000)
????SET?@r?=?''
????SELECT?@r?=?@r?+?','?+?value
????FROM?tb
????WHERE?id=@id
????RETURN?STUFF(@r,?1,?1,?'')
END
GO
--?調用函數
SELECt?id,?values=dbo.f_strHeBin(id)
FROM?tb
GROUP?BY?id
以上方式得到的是根據ID合并的所有記錄,如果要得到相應的單一ID的記錄,則還需要添加一條語句:
假設:以上結果入到臨時表3t3中:
SELECT?id,max(values)?as?values?FROM?#t3?GROUP?BY?id
go
分析結果如下:
SQL?Server?分析和編譯時間:?
???CPU?時間?=?0?毫秒,占用時間?=?7?毫秒。
1--使用sql?全系列版本,自定義合并函數方式
SQL?Server?執行時間:
???CPU?時間?=?0?毫秒,占用時間?=?0?毫秒。
表?'Worktable'。掃描計數?1,邏輯讀取?4030?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
表?'tb'。掃描計數?2,邏輯讀取?46?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
SQL?Server?執行時間:
???CPU?時間?=?1397254?毫秒,占用時間?=?1463680?毫秒。
(1969?行受影響)
(218?行受影響)
表?'Worktable'。掃描計數?0,邏輯讀取?0?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
表?'#t3___000067'。掃描計數?1,邏輯讀取?16?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
SQL?Server?執行時間:
???CPU?時間?=?0?毫秒,占用時間?=?84?毫秒。
SQL?Server?執行時間:
???CPU?時間?=?0?毫秒,占用時間?=?2?毫秒。
總計耗時計:24.4分鐘,這才1969行記錄,這個方法看來在這種情況下不可取。
2?:??sql?2005及以上版本中的新的解決方法,FOR?XML
select?id,stuff(
(select?'-'?+?convert(varchar(4),value)
from?tb
where?id=A.id
order?by?id
for?xml?path('')
),1,1,'')?as?values?
from?tb?A
group?by???id
go
分析結果如下:
SQL?Server?分析和編譯時間:?
???CPU?時間?=?0?毫秒,占用時間?=?0?毫秒。
SQL?Server?執行時間:
???CPU?時間?=?0?毫秒,占用時間?=?0?毫秒。
表?'Worktable'。掃描計數?439,邏輯讀取?32978?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?319?次,lob?物理讀取?0?次,lob?預讀?0?次。
表?'tb'。掃描計數?4,邏輯讀取?92?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
SQL?Server?執行時間:
???CPU?時間?=?1856?毫秒,占用時間?=?1955?毫秒。
總計耗時:2秒鐘。不過這個方法隨著記錄數量的增加,性能也隨之降低,在數據記錄達到20000條的時候,耗時將近2.5分鐘。
3?:??使用臨時表實現字符串合并處理的示例
SELECT?id?,values=CAST(value?as?varchar(8000))
INTO?#t2?FROM?tb
ORDER?BY?id
DECLARE?@col1?varchar(5),@col2?varchar(8000)
UPDATE?#t2?SET
????@col2=CASE?WHEN?@col1=id?THEN?@col2+'-'+values?ELSE?values?END,
????@col1=zo3,
????qs=@col2
SELECT?id,max(values)?values?FROM?#t2?group?by?id
drop?table?#t2
go
分析結果如下:
SQL?Server?分析和編譯時間:?
???CPU?時間?=?7?毫秒,占用時間?=?7?毫秒。
SQL?Server?執行時間:
???CPU?時間?=?0?毫秒,占用時間?=?0?毫秒。
表?'Worktable'。掃描計數?0,邏輯讀取?0?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
表?'tb'。掃描計數?2,邏輯讀取?46?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
SQL?Server?執行時間:
???CPU?時間?=?734?毫秒,占用時間?=?769?毫秒。
(2012?行受影響)
表?'#t2___________000000000065'。掃描計數?1,邏輯讀取?1677?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
SQL?Server?執行時間:
???CPU?時間?=?62?毫秒,占用時間?=?62?毫秒。
(2012?行受影響)
表?'#t2__________000000000065'。掃描計數?1,邏輯讀取?849?次,物理讀取?0?次,預讀?0?次,lob?邏輯讀取?0?次,lob?物理讀取?0?次,lob?預讀?0?次。
SQL?Server?執行時間:
???CPU?時間?=?16?毫秒,占用時間?=?7?毫秒。
(218?行受影響)
SQL?Server?執行時間:
???CPU?時間?=?0?毫秒,占用時間?=?1?毫秒。
SQL?Server?執行時間:
???CPU?時間?=?0?毫秒,占用時間?=?0?毫秒。
???總計耗時:769ms+62ms+15ms=846ms,總費時1秒鐘不到,當數據記錄達到20000條記錄時,性能損耗也不太嚴重,在6-10秒左右。能夠接受。
轉載于:https://www.cnblogs.com/lzj1981/archive/2013/05/01/3053184.html
總結
以上是生活随笔為你收集整理的Sql Server中三种字符串合并方法的性能比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 只列出目录
- 下一篇: cmd-查看历史命令 重定向