从MS SQL删除大数据说开去-3
上一篇 /
下一篇 2012-04-01 10:08:39
/ 个人分类:数据库
再说说基于联接的DELETE,T-SQL支持一种基于联接的DELETE语法,这不是一种标准的
SQL语法。联接本身就有过虑的作用,因为它有一个基于谓词的过滤器(ON子句)。通过联接可以访问另一个表中相关行的属性(列),并在WHERE子句中引用这些属性,这就意味着可以根据对另一个表中相关行的属性定义的过虑器来删除表中的数据行。例如:
PqYr(wt~0
6\;G+w G i,FCZ:K-K4l;Q02lxK5^n'ZAORV0DELETE FROM S5 a|4e$E*t5SG
ulU0 FROM dbo.S5_BinTest_Info AS S551Testing软件测试网$r
k.wR1_!EdZ JOIN dbo.S5_BinTest_Info_Dtl AS DTL 1yd4h)}R'`:g0 ON S5.ID=DTL.ID51Testing软件测试网)qBh$F/B\;| WHERE DTL.QTY=1; #Y'nV-R
y~8j+~7M0 |
,NNE
?Xf0
RMOA`.Q:v\051Testing软件测试网!?QH$C pK`,\5t 这和SELECT语句非常相似,DELETE语句在逻辑上第一个处理的子句是FROM子句(第二行FROM dbo.S5_BinTest_Info AS S5的这个),接着处理WHERE子句,最后才是DELETE子句。51Testing软件测试网1D-U9Wq`j
T-GO8Ci2c&e0 这也可以用查询子句来实现同样的处理:
W{^4c;pS051Testing软件测试网8~ PUce"a9{%}51Testing软件测试网_q7WC5Di
DELETE FROM dbo.S5_BinTest_Info51Testing软件测试网%Iw.D^%WH^/j WHERE EXISTS(SELECT 1 FROM dbo.S5_BinTest_Info_Dtl AS DTL )}P*iPe:pu,g0 WHERE S5_BinTest_Info .ID=DTL.ID AND DTL.QTY=1); |
n*o T1p2b%l&Q1m+u051Testing软件测试网
kkm0uS/i#T||*\
51Testing软件测试网-B?Ku'B 这里的查询子句的方式是标准的SQL语句,我更喜欢使用标准SQL。51Testing软件测试网x |
c0w f#z;cT_n
:h;dc}]e0 再回到我这个工作中的问题,我想用分批删除的方式来处理。一次删除合理数据的记录,多删除几次就可以了。51Testing软件测试网D_lZ#H
l"k"VxR)d
Dl#b"H
o{)X0 由于我为里是有ID的,所以一次删除一个ID号的记录,以下是更改后的循环方式实现源码。
L3L;z(Q fG
o051Testing软件测试网$B,cwr#B\&^
NJTo)]bZ.|3P6t7^~01: --2012-03-30,因删除大数据问题,以下更改为分批删除的方式实现 3|A/BK)S2Hf02: DECLARE @MINID INT; PVhza~W4[03: DECLARE @N INT; 7e&H9pxbb.FL[04: --取出要删除的90天前的记录的ID H9O/a1Wi u&RJ05: SELECT BinTestID into #S5ID .m(~5^A
n,hO!WH06: from dbo.S5_BinTest_Info51Testing软件测试网g:Q4buD7e 7: where TS <dateadd(dd,-90,getdate()); U.y4tD`4{!w3S$k08: --以要删除的ID数量为循环变量,因为ID号可能不连续51Testing软件测试网 I:sQU:M0P[}J 9: SELECT @N=(SELECT COUNT(1) FROM #S5ID); ,PL.tU'CR%n7_?N]8d010: WHILE (@N>0)51Testing软件测试网 my%J8e)\5G)aW 11: BEGIN51Testing软件测试网{J'V+T5v-ANAG 12: -- 一次删除一个ID对应的数据 .k.I?
_g `x013: SELECT @MINID=MIN(BinTestID) FROM #S5ID;51Testing软件测试网,@-]1oSL3o1g6S)f 14: DELETE FROM dbo.S5_BinTest_Detail51Testing软件测试网`/v7I!o%j@vI9o 15: whereBinTestID=@MINID;51Testing软件测试网-s:T
D.w2X5V_1[*O 16: DELETE from dbo.S5_BinTest_Info51Testing软件测试网*[q)l)nAPF-G 17: whereBinTestID=@MINID;51Testing软件测试网As!@2Q;xi` 18: --从临时表中去除已删除的ID号 Q*x&w8{`"BN$x019: DELETE #S5ID WHEREBinTestID=@MINID; 4J+Jj)@0L@7O3d3Qf020: --更改剩余要删除的ID数,这是循环变量51Testing软件测试网'l0D-y[:U(H
~H 21: SELECT @N=(SELECT COUNT(1) FROM #S5ID); oh(q,M:]~+KO-~8]022: END W`+D2T2}^023: DROP TABLE #S5ID; |
51Testing软件测试网e"S[1j\,Ce51Testing软件测试网
GDeyu{I
2a-rMb2L.x,Y:b0 如果对于没有ID的数据表,我们可以用TOP的方式来删除。51Testing软件测试网 K?2Uc{2? R
51Testing软件测试网fTm;jr3r 我使用这样的方式执行时,日志基本没有增长,因为删除一次很少的数据,成功后会释放,再使用。
0n |+X:f%~QN
w!l:T3}j051Testing软件测试网R`/SxEn 您,删除数据时考虑语法和条件还有大量数据的日志增长空间问题了吗?51Testing软件测试网J2g*Oj-n/l;e
F9W2g
收藏
举报
TAG: