1. 程式人生 > 資料庫 >SQL------去重方案------千百萬級資料量

SQL------去重方案------千百萬級資料量

以下方案暫定,後面會試一下效果。

主要的思路是分段去重,因為直接一個語句去重太慢了。

指令碼試著分段數量合理了以後,就做成程式,程式多開來處理不同的分段。

--首先按照【txt】欄位建立索引
--然後下面的指令碼會按照這個索引排序,分段,生成【對每個分段查詢重複id】的sql語句。
--再下一步,想在程式內用dataAdapter進行刪除,因為比用delete語句快一些。
--寫程式前先用這個指令碼試試,看看分段數量多少合適。

--總行數--大體
declare @rowCount int = (
    select max(ROW_NUMBER) from 
    (
        select 
            ROW_NUMBER() OVER(order by txt) as ROW_NUMBER
        from ZZ1
    ) t
)

--每個分段的行數
declare @FenDuanCount int = 1000

--最大的左右界限
declare @maxRightIdx int = @rowCount /@FenDuanCount +1
declare @maxLeftIdx int = @rowCount /@FenDuanCount 

--左右界限表
if object_id('tempdb..#tIdx') is not null drop table #tIdx
select 
    @maxLeftIdx as LeftIdx
    ,@maxRightIdx as RightIdx
into #tIdx

--求出每個左右界限
declare @curLeftIdx int = @maxLeftIdx -1
while(@curLeftIdx >=0)
begin
    insert into #tIdx (LeftIdx,RightIdx) values (@curLeftIdx,@curLeftIdx+1)
    set @curLeftIdx = @curLeftIdx - 1
end

--生成語句若干--用於查詢重複的id
select 
'  
if object_id(''tempdb..#tFenDuan'') is not null drop table #tFenDuan
--分段資料
select 
    *
into #tFenDuan
from 
(
    select 
        ROW_NUMBER() OVER(order by txt) as ROW_NUMBER
        ,ID
        ,txt
    from ZZ1
) t
where ROW_NUMBER between '+Convert(varchar(100),LeftIdx*@FenDuanCount)+' and '+ convert(varchar(100),RightIdx*@FenDuanCount) +
'
--重複的資料
select * 
FROM #tFenDuan t 
WHERE t.ROW_NUMBER > (
    SELECT MIN(n.ROW_NUMBER) 
    FROM #tFenDuan n 
    WHERE t.txt = n.txt)
'
from #tIdx