sql遍歷解析
在sql的儲存過程,函式中,經常需要使用遍歷(遍歷table),其中游標、臨時表等遍歷方法很常用。面對小資料量,這幾種遍歷方法均可行,但是面臨大資料量時,就需要擇優選擇,不同的遍歷方法,在效率上存在指數級別的差異
本文主要針對大量資料的遍歷,當資料量小時;可以隨意選擇一種遍歷方法。
例項資料如下:一共177471條資料
需求:更新ldbm,其中ldbm=lxbm+ldxlh;即update v_tl_t_ld_all set ldbm=lxbm+ldxlh:為了演示遍歷,我們迴圈遍歷,一條條資料更新,同時統計其效率,並初略分析其原因
1.游標遍歷
游標的遍歷
游標是一種最常用的方法,使用起來比較簡單,主要步驟為:宣告游標,開啟游標,使用游標,關閉游標和釋放游標。示例**如下
1游標是最直接的從表裡面一條條的資料取出,並進行update操作,沒有涉及到索引,如果資料量大,其取資料和update都將消耗大量的時間,因此此種方式效率很低。--方法1:游標2--
宣告變數
3declare
4@ldbm
asnvarchar(20),5
@ldxlh
asnvarchar(20),6
@lxbm
asnvarchar(20),7
@crowid
asnvarchar(80);8
9--宣告游標
10declare t_ld cursor fast_forward for
11select
ldbm,ldxlh,lxbm,crowid
12from
v_tl_ld_all1
1314
open
t_ld;
1516
--取第一條記錄
17fetch
next
from t_ld into
@ldbm,@ldxlh,@lxbm,@crowid;18
19while
@@fetch_status=0
20begin
21--
操作22
update v_tl_ld_all1 set ldbm=
@ldbm+'
'+@ldxlh
where crowid=
@crowid;23
24--
取下一條記錄
25fetch
next
from t_ld into
@ldbm,@ldxlh,@lxbm,@crowid;26
end27
28--
關閉游標
29close
t_ld;
3031
--釋放游標
32deallocate t_ld;
從對資料庫的操作上,其一共運算元據庫2n+1次,將資料取出並存入游標(申明游標):1次;update更新操作:n次;從游標取記錄:n次;將資料儲存到游標和消耗了大量的記憶體,且隨著資料量的增大,消耗值將呈現指數增加
更新上述177474條資料一共消耗了2h48min37s
2.臨時表
使用游標不僅僅存在效能的問題,也違背面向集合思想的問題,所以我們有必要用面向集合的思想去找到一種更好的解決方案,即使用物件導向的思想,構造乙個臨時表,然後直接操作臨時表,**如下。
1使用臨時表,和游標類似,同時將大量的資料儲存到記憶體中,但是隨著遍歷的進行,臨時表的資料量越來越小,可以相當程度的降低記憶體的消耗,但是需要不停的與table表做互動,一共操作3n+1次資料庫;--方法2:使用臨時表2--
建立臨時表
3select
ldbm,ldxlh,lxbm,crowid
4into
#t_ld
5from
v_tl_ld_all167
--宣告變數
8declare
9@ldbm
asnvarchar(20
),10
@ldxlh
asnvarchar(20
),11
@lxbm
asnvarchar(20
),12
@crowid
asnvarchar(80
);13
14while
exists(select crowid from
#t_ld)
15begin
16--
也可以使用top 1
17set
rowcount118
select
@lxbm
= lxbm, @ldxlh
= ldxlh,@crowid
=crowid from
#t_ld;
19update v_tl_ld_all1 set ldbm=
@lxbm+'
'+@ldxlh
where crowid=
@crowid;20
setrowcount021
22delete
from #t_ld where crowid=
@crowid;23
end
此種方式,更新上述資料一共消耗:1h:45min:37s
3.索引表
索引表和臨時表的操作類似;唯一區別在於在建立臨時表是,新增乙個索引,然後通過此索引從表中取資料;效率上有所提公升,但是增加了變數的輸出,**如下
1臨時索引表和臨時表類似,區別在於:在取資料的時候,通過索引的方式取資料;相比臨時表,減少了頻繁運算元據庫的次數,相比游標,減少了與資料庫互動的時間(索引檢索速度更快)--方法3:使用索引表2--
建立臨時表3if
exists(select name from sysobjects where name=
'tmptable
')
4drop
table tmptable --
存在則刪除
5create
table
tmptable(
6 nid int
primary
keyidentity(1,1), --
主鍵,自增
7 crowid nvarchar(90
), 8 lxbm nvarchar(20
),9 ldxlh nvarchar(6
),
10)
11--
插入資料
12insert
into
tmptable(crowid,lxbm,ldxlh)
13select crowid,lxbm,ldxlh from
v_tl_ld_all1
1415
--宣告變數
16declare
17@index
int,
18@countnum
int,
19@ldbm
asnvarchar(20
),20
@ldxlh
asnvarchar(20
),21
@lxbm
asnvarchar(20
),22
@crowid
asnvarchar(80
);23
24select
@countnum
=count(1) from
tmptable;
25set
@index=0
;26--遍歷
27while
@index
<
@countnum
28begin
29set
@index
=@index+1
;30select
@lxbm
= lxbm, @ldxlh
= ldxlh,@crowid
=crowid from tmptable where nid=
@index
31update v_tl_ld_all1 set ldbm=
@lxbm+'
'+@ldxlh
where crowid=
@crowid;32
end33
34--
刪除臨時索引表
35drop
table tmptable
更新上述資料,一共消耗:1h2,min
比較而言,建議盡可能少的使用游標,不僅消耗記憶體,**量也稍微複雜一些;當資料量小的時候,建議使用臨時表(**比較輕量),而隨著資料的增加,建議使用索引表
SQL Server遍歷表的幾種方法
原文 sql server遍歷表的幾種方法 在資料庫開發過程中,我們經常會碰到要遍歷資料表的情形,一提到遍歷表,我們第一印象可能就想到使用游標,使用游標雖然直觀易懂,但是它不符合面向集合操作的原則,而且效能也比面向集合低。當然,從面向集合操作的角度出發,也有兩種方法可以進行遍歷表的操作,總結起來,遍...
SQL Server遍歷表的幾種方法
在資料庫開發過程中,我們經常會碰到要遍歷資料表的情形,一提到遍歷表,我們第一印象可能就想到使用游標,使用游標雖然直觀易懂,但是它不符合面向集合操作的原則,而且效能也比面向集合低。當然,從面向集合操作的角度出發,也有兩種方法可以進行遍歷表的操作,總結起來,遍歷表有下面幾種方法。使用游標 使用表變數 使...
SQL Server遍歷表的幾種方法
閱讀目錄 在資料庫開發過程中,我們經常會碰到要遍歷資料表的情形,一提到遍歷表,我們第一印象可能就想到使用游標,使用游標雖然直觀易懂,但是它不符合面向集合操作的原則,而且效能也比面向集合低。當然,從面向集合操作的角度出發,也有兩種方法可以進行遍歷表的操作,總結起來,遍歷表有下面幾種方法。使用游標 使用...