一些看似簡單的數(shù)據(jù)操作,當(dāng)作用于海量數(shù)據(jù)集時(shí),就會(huì)出現(xiàn)“意料之外,卻在情理之中”的問題,海量數(shù)據(jù)操作,需要采用特殊方法,才能“曲徑通幽”。在刪除海量數(shù)據(jù)時(shí),需要注意日志的增長,索引碎片的增加和數(shù)據(jù)庫的恢復(fù)模式,特別是利用大容量日志操作,來減少日志的增長和提高數(shù)據(jù)插入的速度。對(duì)于大數(shù)據(jù)去重,通過一些小小的改進(jìn),比如創(chuàng)建索引,設(shè)置忽略重復(fù)值選項(xiàng)等,能夠提高去重的效率。

一,從海量數(shù)據(jù)中刪除數(shù)據(jù)

從海量數(shù)據(jù)表中刪除一半數(shù)據(jù),看似簡單,使用delete命令,如果真這么干,SQL Server產(chǎn)生的事務(wù)日志暴增,估計(jì)會(huì)把服務(wù)器硬盤爆掉。數(shù)據(jù)庫的恢復(fù)模式會(huì)影響日志文件的增長,在刪除海量數(shù)據(jù)時(shí),根據(jù)采用的方法,相應(yīng)地把恢復(fù)模式設(shè)置為simple,或bulk_logged 模式,能夠在很大程度上減少刪除操作產(chǎn)生的事務(wù)日志,從而避免日志暴增。

另外,在刪除數(shù)據(jù)時(shí),把表上的多余索引刪除(注意,是刪除多余的索引),只保留一個(gè)必需的索引;在數(shù)據(jù)刪除完成之后,再重建索引,能夠提高數(shù)據(jù)刪除操作的性能。有人做過實(shí)驗(yàn),從存儲(chǔ)1.6億條記錄的大表中刪除數(shù)據(jù),每刪除400萬條要消耗1.5 - 3小時(shí),越到后面速度越慢,為什么?這是因?yàn)?,每次刪除數(shù)據(jù)時(shí),數(shù)據(jù)庫都要相應(yīng)地更新索引,這是很慢的硬盤 IO操作,并且,越到后面,索引碎片越多,更新索引就越慢,這就是在刪除400萬條記錄時(shí),一開始只消耗1.5小時(shí),后面要消耗3小時(shí)原因。

最后,根據(jù)保留數(shù)據(jù)占總數(shù)據(jù)量的比例,選擇不同的方法刪除數(shù)據(jù)。如果大表中保留的數(shù)據(jù)較少,可以先把保留的數(shù)據(jù)存儲(chǔ)到臨時(shí)表中,然后,把原始表刪除,這樣能夠利用大容量日志操作,來減少日志的增長和提高數(shù)據(jù)插入的速度。

1,循環(huán)刪除,避免日志文件暴增

在從海量數(shù)據(jù)表中刪除大量數(shù)據(jù)時(shí),為了避免日志文件暴增,通常采用循環(huán)刪除方法:首先設(shè)置恢復(fù)模式為simple,然后每次刪除操作都只刪除部分?jǐn)?shù)據(jù),這樣,當(dāng)單個(gè)刪除操作執(zhí)行完成時(shí),事務(wù)日志會(huì)被及時(shí)清理,事務(wù)日志一般保持單個(gè)刪除操作的事務(wù)日志量。

循環(huán)刪除的偽代碼如下,該方法仍有一些局限性,耗時(shí)過長,并且會(huì)長期使數(shù)據(jù)庫處于簡單恢復(fù)模式下:

萬碼學(xué)堂,電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

--ALTER DATABASE database_name SET RECOVERY SIMPLE ;  while @index<@EndIndexbegin
    delete table_name 
    where index<=@index;    set @index+=@Incrementend

萬碼學(xué)堂,電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),Java培訓(xùn),JavaEE開發(fā)培訓(xùn),青島軟件培訓(xùn),軟件工程師培訓(xùn)

2,將數(shù)據(jù)插入導(dǎo)其他表中,