【MySQL】大數據量表添加字段


前幾天因為需求調整,需要在某張表中添加一個新的字段,而要添加字段的表,正好是我們庫中最大的一張表,表中大約有3300萬條記錄,占用空間32.5G,直接在表上添加字段,很容易卡死。

網上找了一下大數據量表添加字段的帖子,帖子數量還是很多的,套路也都差不多,主要就是兩種方案:

方案一:通過創建備份表的方式,步驟如下:

1.創建臨時表account_bill_temp

create table account_bill_temp like account_bill;

2.在新表中添加字段

alter table account_bill_temp add columu bill_id varchar(64) comment '賬單id' after bill_amount;

3.把舊表中的數據遷移到新表中

insert into account_bill_temp (column1,column2,...) select column1,column2,... from account_bill;

4.修改兩張表的表名

rename table account_bill to account_bill_bak;
rename table account_bill_temp to account_bill;

 

方案二:通過復制數據文件的方式,步驟如下:

1.將表中的數據放到數據文件中

select * from account_bill into outfile '/mysql-files/account.txt'; 

2.創建臨時表account_bill_temp

create table account_bill_temp like account_bill;

3.把舊表中的數據遷移到新表中

load data infile '/mysql-files/account.txt' into table account_bill_temp;

 

大家可能發現以上兩種方案是有區別的,方法二中並沒有添加字段的操作。其實最開始,我是按照方案一添加的字段,但是在執行第三步insert into ... select ...語句的時候,數據庫卡死了。然后我就又去網上扒拉,發現了方案二。但是方案二有個問題,就是要求臨時表的表結構和原表一致,無法添加字段,只能用於備份數據等操作,所以方案二對我們的問題其實是沒啥意義的。之所以把方案二也列出來,是因為如果只是備份數據的話,方案二的執行效率要比方案一高很多(據說能達到20倍以上)。

 

方案二走不通,於是我們只能又回到了方案一。方案一的主要問題就是執行第三步insert into ... select ...語句的時候會卡死,數據遷移到3100萬左右的時候,臨時表中的數據不再發生變化,數據容量也卡在了25.9G不再增加。卡死的原因沒有定位到,我們只是試着去尋找效率更高的方案。其實最終的方案也比較簡單,就是account_bill表存在5個索引,其中一個索引由6個字段組成,我們在方案一的第一步后面加了一步,刪除主鍵和所有索引

第一次按方案一執行的時候,帶着主鍵和索引執行insert into ... select ...語句,從開始到遷移3100萬數據卡死,執行了3個小時左右。第二次執行,刪除主鍵和索引,執行insert into ... select ...語句,全部數據遷移只用了半小時。數據遷移后再把主鍵和索引加上,添加主鍵用了20分鍾,添加5個索引的耗時都在10分鍾以下,一個多小時完成整張表的遷移工作。總結最終方案如下:

1.創建臨時表account_bill_temp

create table account_bill_temp like account_bill;

2.刪除臨時表的主鍵和索引

alter table account_bill_temp drop PRIMARY KEY;
alter table account_bill_temp drop index index_name; //注意修改索引名

3.在新表中添加字段

alter table account_bill_temp add columu bill_id varchar(64) comment '賬單id' after bill_amount;

4.把舊表中的數據遷移到新表中

insert into account_bill_temp (XXX,XXX,...) select XXX,XXX,... from account_bill;

5.添加主鍵和索引

alter table account_bill_temp add primary key (id);
alter table account_bill_temp add index index_name (column1,column2);

6.修改兩張表的表名

rename table account_bill to account_bill_bak;
rename table account_bill_temp to account_bill;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM