程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 拆表用的MySQL存儲過程

拆表用的MySQL存儲過程

編輯:MySQL綜合教程

MySQL存儲過程用途很廣泛,下面就為您介紹拆表用的MySQL存儲過程,希望對您學習MySQL存儲過程方面能夠有所幫助。

mysql表或分表的數據達到一定量也許是800w或者1000w..)這個時候非常需要再分表,簡單的辦法是直接寫
--假設根據user_id分表,分成64張

  1. insert into table_new_0000 select * from table_old where mod(user_id,64)=0;  
  2. insert into table_new_0001 select * from table_old where mod(user_id,64)=1;  
  3. ...  

一共64條sql,OK 搞定。  但是這個一張表被全表掃描了64次,做的無用功比較多,而且導致停機時間比較長。

雖然MySQL存儲過程不是很熟,稍稍學習了下寫了兩個腳本,一個全量+一個增量腳本完成表的拆分。
線上庫也實踐了下,8個分表,每個分表1000W記錄拆分到64個分表。
全量 時間 150分鐘,全量的時候幾個分表可以一起跑,我是同時跑3個分表
增量 時間 每個分表4分鐘 4個一起跑,一共是 8分鐘搞定。 這樣停機時間加上應用的發布一共只需要20分鐘就可以搞定了。

附腳本:

###################
delimeter //

-----------
--- 全量腳本:

  1. CREATE PROCEDURE  sp_xf_move_item()  
  2. begin  
  3. declare v_exit int default 0;  
  4. declare v_spid bigint;  
  5. declare v_id bigint;  
  6. declare i int default 0;  
  7. declare c_table int;  

--定義游標要分拆的表,定義一個數量的截止時間)

  1. declare c_ids cursor for select id,user_id from item_records_0000 where gmt_modified < '2010-8-25 00:00:00';  
  2. declare  continue handler for not found set v_exit=1;  
  3. open c_ids;  
  4. repeat  

--將需要的值裝入變量

  1. fetch c_ids into v_id,v_spid;  
  2. if v_exit = 0 then  
  3. set @vv_id = v_id;  

--根據取模字段獲取數據存在的表

  1. select mod(v_spid,64) into c_table;  

--組裝動態sql

  1. SET @SQL_CONTEXT =  
  2. CONCAT('insert into item_record_',  
  3. LPAD(c_table, 4, 0),  
  4. ' select * from item_records_0000 where id = ?');  
  5.  
  6. PREPARE STMT FROM @SQL_CONTEXT;  
  7. --執行sql  
  8. EXECUTE STMT using @vv_id;  
  9. DEALLOCATE PREPARE STMT;  
  10. end if;  
  11. set ii=i+1;  
  12.  

--100條提交一次,以提高效率,記得執行存儲過程前設置auto_commit

  1. if mod(i,100)=0 then commit;  
  2. end if;  
  3. until v_exit=1 
  4. end repeat;  
  5. close c_ids;  
  6. commit;  
  7. end;  
  8. //  
  9.  
  10. -----------  
  11. set auto_commit=0;  
  12. call  sp_xf_move_item();  
  13.  
  14. #### 增量腳本 ######  
  15.  
  16. CREATE PROCEDURE sp_xf_add_item()  
  17. begin  
  18. declare v_exit int default 0;  
  19. declare v_spid bigint;  
  20. declare v_id bigint;  
  21. declare i int default 0;  
  22. declare c_table int;  
  23. declare c_ids cursor for select id,supplier_id from item_records_0000 where gmt_modified >= '2010-8-25 00:00:00';  
  24. declare  continue handler for not found set v_exit=1;  
  25. open c_ids;  
  26. repeat  
  27.  
  28. fetch c_ids into v_id,v_spid;  
  29. if v_exit = 0 then  
  30. set @vv_id = v_id;  
  31. set @v_row=0;  
  32. select mod(v_spid,64) into c_table;  
  33.  

--判斷數據是否已經存在

  1. SET @SQL_C =  
  2. CONCAT('select count(*) into @v_row from item_record_',  
  3. LPAD(c_table, 4, 0),  
  4. ' where id = ?');  
  5.  
  6. PREPARE STMT_C FROM @SQL_C;  
  7. EXECUTE STMT_C using @vv_id;  
  8. DEALLOCATE PREPARE STMT_C;                         
  9.  
  10. SET @SQL_INSERT =  
  11. CONCAT('insert into bbc_item_record_',  
  12. LPAD(c_table, 4, 0),  
  13. ' select * from item_records_0000 where id = ?');  
  14.  
  15. PREPARE STMT_I FROM @SQL_INSERT;           
  16.  
  17. SET @SQL_DELETE =  
  18. CONCAT('DELETE FROM bbc_item_record_',  
  19. LPAD(c_table, 4, 0),  
  20. ' where id = ?');  
  21. PREPARE STMT_D FROM @SQL_DELETE;       

--如果數據已經存在,則先delete在insert             

  1. if @v_row>0 then   
  2.  
  3. EXECUTE STMT_D using @vv_id;  
  4. DEALLOCATE PREPARE STMT_D;  
  5.  
  6. end if;  
  7. EXECUTE STMT_I using @vv_id;  
  8. DEALLOCATE PREPARE STMT_I;         
  9.  
  10. end if;  
  11. set ii=i+1;  
  12. if mod(i,100)=0 then commit;  
  13. end if;  
  14. until v_exit=1 
  15. end repeat;  
  16. close c_ids;  
  17. commit;  
  18. end;  
  19. //  
  20.  
  21. -------  
  22.  

如果全量和增量之間的時間拖的比較長,那麼可以設置時間,多做幾次增量已縮短最後的停機時間,你懂的。。。
call sp_xf_add_item()//
 

深入探討MySQL鎖機制

MySQL字段中的集合

MySQL字段類型簡介

Mysql外鍵用法分析

詳解MySQL數據表類型

   

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved