mysql之儲存過程(四) 批量更新操作

2022-05-06 08:51:10 字數 3167 閱讀 7754

最近有乙個場景,在生產環境的乙個庫中,新增了乙個字段。需要從另乙個關聯表中找到相當的字段回填。

影響資料數百萬條。

首先,不能使用一條大的update語句來更新,這個鎖太大,容易產生鎖徵用,造成死鎖。

update b a set new_column=(select other_col from a b where status=9 and a.busi_id=b.busi_id and b.pid=1242343324),modified=now() where pid=21343

因此,寫乙個儲存過程解決,儲存過程一條條處理,太慢且消耗本地io,所以寫了個批量更新的儲存過程。

如下:delimiter &&

create procedure updatetimev1(in comcount bigint)

begin

#routine body goes here...

declare i int;

set i=0;

set @sum=(select count(distinct busi_id

) from `b` where `pid`=1242343324 and status=9 );

set @log = "log query ....";

select concat(@log,@sum," 條");

while i<=@sum do

set i=i+1;

set @busi_id =( select distinct busi_id from `a` where `pid`=1242343324  limit i,1);

set @other_col

=(select other_col

from `b` where `pid`=1242343324 and yn =1 and `busi_id

` = @busi_id

limit 1);

if @busi_id is null then

select concat(@log," busi_id is null");

elseif @other_col is null then

select concat(@log," other_col is null");

else

#start transaction;

/** 關閉事務的自動提交 */  

set autocommit = 0;

update a set new_column =@other_col,modified = now() where  `pid`=1242343324  and busi_id=@busi_id  and status =15;  

##   if mod(i,comcount)=0 then commit;

if mod(i,1000)=0 then commit;

end if;

end if;

end while;

commit; #最後不足1000條時提交

set autocommit = 1;

end&&

delimiter ;

上面的儲存過程效率還不夠快,並且limit i,1會導致,儲存過程在執行到中間某一時刻後會取不到資料,導致漏資料。根據經驗值,如果影響資料量在500w之內,可以直接游標取出來更新,而且不會有漏掉的。另外,根據經驗值,批量提交3000到5000是可以的,當然保險期間可以1000到2000提交一次。

修改後的儲存過程正下:

delimiter &&

create procedure updatetimev2(in comcount bigint)

begin

declare c_busi_id

bigint(20);

declare i int default 0;

declare cur_award cursor for

select distinct busi_id

from `a` where `pid`=1242343324

and yn =1 and order_time is null ;

open cur_award;

loop

fetch cur_award into c_busi_id

;set i=i+1;

set @other_col =(select cast(other_col as date) from `b` where `platform_id`=1242343324

and yn =1 and `busi_id

` = c_busi_id

limit 1);

if @other_col is null then

select concat(@log," other_col is null");

else      

set autocommit = 0;

select concat("before update c_busi_id

is ",c_busi_id

," other_col is ",@other_col);

update a set order_time =@other_col,modified = now() where  `pid`=1242343324

and busi_id

=c_busi_id

and yn =1;  

select concat("after update c_busi_id

is ",c_busi_id

);if mod(i,comcount)=0 then

select concat("befor update commit i is ",i);

commit;

end if;

end if;

end loop;

commit;

set autocommit = 1;

end&&

delimiter ;

經測試優化後的儲存過程的效能要遠遠優化優化前的,且不會漏記錄。

備註:1、測試了一下一條一條執行,一小時大概20w行更新

2、mod(i,1000)

這塊得注意 ,如果把set i=i+1;

放到最後,在上面的儲存過程批量就不會生效。

3、刪除儲存過程drop procedure updatetimev1;

Solr部署配置(四)批量匯入資料

一 solr自帶匯入外掛程式dataimporte設定 1 在solrconfig.xml檔案中新增如下內容,引入dataimport功能,並設定配置檔案位置。d dev test solr tomcat solr db conf db data config.xml 二 匯入資料 1 從資料庫匯入...

unittest單元測試框架(四)批量執行測試用例

批量執行測試用例,比較合理的做法是把相關的幾條用例放到乙個.py 檔案裡,把所有.py 檔案放到乙個資料夾下,然後通過乙個程式執行資料夾下面的所有用例。testcase.py dos命令一直有錯。如果大家對於學習python有任何問題,學習方法,學習路線,如何學習有效率的問題,可以隨時來諮詢我,或者...

mysql 儲存過程批量更新

最近做乙個批量更新的操作,由於是臨時需求,就想著在資料庫直接操作,不在 裡動手了,結合網上的一些資料,做如下處理 1.先建立乙個臨時表,匯入需要變動的資料 drop table if exists t barcode create table t barcode barcode varchar 32...