使用存儲過程向數據庫批量插入數據

<一> 前言

    最近有個需求,須要向數據庫併發批量插入數據。
mysql

    最開始使用存儲過程,相似這樣的:
sql

 delimiter // 
 CREATE PROCEDURE load_part_tab()
 begin
     declare v int default 0;
     while v < 8000000
     do
         insert into part_tab
         values (v,'testing partitions',adddate('1995-01-01',(rand(v)*36520) mod 3652));
          set v = v + 1;
     end while;
 end
 //
 delimiter ;

這是單條屢次插入。時間消耗徹底不能忍,2萬條記錄,耗時近半個小時。數據庫

後改成使用存儲過程,批量插入,10個併發,每一個插入2萬條記錄,共耗時119s。併發

查閱了網上的一些資料,先整理以下。我本身的代碼,由於公司業務問題就不公佈。測試

<二>過程

2.1 創建數據庫表:

CREATE TABLE song ( 
          id int(11) NOT NULL AUTO_INCREMENT COMMENT 'Autoincreament element', 
          name text NOT NULL, 
          datetime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
          rank int(11) NOT NULL, 
          PRIMARY KEY (id) 
) ENGINE=MyISAM AUTO_INCREMENT=8102001 DEFAULT CHARSET=gbk

2.2 建立處理的存儲過程:

DELIMITER //
DROP PROCEDURE IF EXISTS sp_insert_batch;
CREATE  PROCEDURE sp_insert_batch(IN number int(11))
BEGIN
  declare i int(11);
  set i = 1;
  WHILE i <= number DO
    if mod(i,2000)=1 then
       set @sqltext =concat('(''',concat('t',i),''',''',now(),''',',ceil(10*rand()),')');
    elseif mod(i,2000)=0 then
       set @sqltext=concat(@sqltext,',(''',concat('t',i),''',''',now(),''',',ceil(10*rand()),')');
       set @sqltext=concat('insert into song (name,datetime,rank) values',@sqltext);
       prepare stmt from @sqltext;
       execute stmt;
       DEALLOCATE PREPARE stmt;
       set @sqltext='';
    else 
       set @sqltext=concat(@sqltext,',(''',concat('t',i),''',''',now(),''',',ceil(10*rand()),')');
    end if;
    set i = i + 1;
  END WHILE;
  if @sqltext<>'' then
     set @sqltext=concat('insert into song (name,datetime,rank) values',@sqltext);
     prepare stmt from @sqltext;
     execute stmt;
     DEALLOCATE PREPARE stmt;
     set @sqltext='';
  end if;
END //
DELIMITER ;

解釋一下:2000 條一個批次插入,經過拼接外面的values,而後使用 insert into values (),(),... 這樣批量插入。code

3. 使用 mysqlslap 測試如:

mysqlslap -uroot -p --concurrency=10,20,30,40,50,60 --engine=innodb --create-schema='scmtg_dev' --query='call sp_insert_batch(2000);'

4.測試結果:

每一個客戶端插入2萬條記錄,10個、20個、30個、40個(固然這個測試量是極小的),走勢以下圖:element

<三> 分析

  1. 批量插入的效率明顯是要遠高於單條屢次插入,這個毋庸置疑。單條屢次插入,一個客戶端2萬條須要近半個小時;而批量插入 10個客戶端,每一個2萬條,才120s。it

  2. 存儲過程,sql 的拼接仍是比較麻煩的。要多測試,避免錯誤。
    io

相關文章
相關標籤/搜索