使用MySQL的SELECT INTO OUTFILE ,Load data file,Mysql 大量數據快速導入導出


使用MySQL的SELECT INTO OUTFILE 、Load data file

LOAD DATA INFILE語句從一個文本文件中以很高的速度讀入一個表中。當用戶一前一后地使用SELECT ... INTO OUTFILE 和LOAD DATA INFILE 將數據從一個數據庫寫到一個文件中,然后再從文件中將它讀入數據庫中時,兩個命令的字段和行處理選項必須匹配。否則,LOAD DATA INFILE 將不能正確地解釋文件內容。

假設用戶使用SELECT ... INTO OUTFILE 以逗號分隔字段的方式將數據寫入到一個文件中:

  1. SELECT * INTO OUTFILE 'data.txt' FIELDS TERMINATED BY ',' FROM table2;

為了將由逗號分隔的文件讀回時,正確的語句應該是:

  1. LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY ',';

如果用戶試圖用下面所示的語句讀取文件,它將不會工作,因為命令LOAD DATA INFILE 以定位符區分字段值:

  1. LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY '\t';

下面是我用來導入導出的命令:

使用MySQL的SELECT INTO OUTFILE ,Load data file,Mysql 大量數據快速導入導出-新鄉seo|網站優化,網站建設_微信公眾號:zeropython—昊天博客
  1. select * into outfile 'ddd.txt' fields terminated by ',' from dn_location;
  2. load data infile 'ddd.txt' into table dn_location2  FIELDS TERMINATED BY ',';

通過該方法導出的數據,是將各字段(只有數據,不導出表結構)數據存在一個文件中,中間以逗號分隔,因為文件中並不包含數據庫名或者表名,因此需要在導入導出的時候些明確。該方法在18分鍾內導出1.6億條記錄,46min內導入6472W條記錄,平均速度:8442W條/h。mysql官方文檔也說明了,該方法比一次性插入一條數據性能快20倍。

【額外測試1】在新的表結構中增加主鍵,並增加某一列自增,查看主鍵索引對插入效率的影響

【結論】導出效率沒有變化,導入效率35min中導入4600W條記錄,平均速度:7886W/h,考慮到測試次數很少,不能直接下結論,但至少明確該操作不會有明顯的效率下降。

【測試語句】

  1. SELECT MOTOR_ID,LAT,LON,UPLOADTIME,RECEIVETIME,STATE_ID,SYS_STATE_ID,SPEED,DIR,A,GPRS,DISTANCE,WEEKDAY,GPSLOCATE  INTO OUTFILE 'import2.txt' FROM dn_location3;
  2. LOAD DATA INFILE 'import2.txt' INTO TABLE dn_location_withkey(MOTOR_ID,LAT,LON,UPLOADTIME,RECEIVETIME,STATE_ID,SYS_STATE_ID,SPEED,DIR,A,GPRS,DISTANCE,WEEKDAY,GPSLOCATE);

【額外測試2】在新建的表中對一個varchar類型字段增加索引,再往里導入數據,查看對插入效率的影響。

【結論】導入4600W條記錄耗時47min,效率確實有所降低,比僅有主鍵索引的測試多了12分鍾,從這里看插入效率排序: 沒有任何索引 > 主鍵索引  >  主鍵索引+其他索引。

【額外測試3】在新建表中不加索引導入數據,完全導入后再建索引,查看建立索引時間

【結論】(1)表數據4600W,建立索引時間10min;表數據1.6億條,建立索引時間41min,由此可見建立索引的時間與表的數據量有直接關系,其他影響因素比較少;(2)從此處看先插入數據再建索引與先建索引再批量插入數據時間上差距不大,前者稍快一些,開發中應根據實際情況選擇。

(3)使用mysqldump ,source

  1. mysqldump -u root -p -q -e -t  webgps4 dn_location2 > dn_location2.sql
  2. mysqldump -u root -p -q -e -t --single-transaction  webgps4 dn_location2 > dn_location2.sql
  3. source dn_location2.sql

以上是導入導出數據的語句,該方法15分鍾導出1.6億條記錄,導出的文件中平均7070條記錄拼成一個insert語句,通過source進行批量插入,導入1.6億條數據耗時將近5小時。平均速度:3200W條/h。后來嘗試加上--single-transaction參數,結果影響不大。另外,若在導出時增加-w參數,表示對導出數據進行篩選,那么導入導出的速度基本不變,篩選出的數據量越大,時間越慢而已。對於其中的參數這里進行說明:

–quick,-q
該選項在導出大表時很有用,它強制 mysqldump 從服務器查詢取得記錄直接輸出而不是取得所有記錄后將它們緩存到內存中。

--extended-insert, -e
使用具有多個VALUES列的INSERT語法。這樣使導出文件更小,並加速導入時的速度。默認為打開狀態,使用--skip-extended-insert取消選項。

--single-transaction

該選項在導出數據之前提交一個BEGIN SQL語句,BEGIN 不會阻塞任何應用程序且能保證導出時數據庫的一致性狀態。它只適用於多版本存儲引擎,僅InnoDB。本選項和--lock-tables 選項是互斥的,因為LOCK TABLES 會使任何掛起的事務隱含提交。要想導出大表的話,應結合使用--quick 選項。在本例子中沒有起到加快速度的作用
mysqldump -uroot -p --host=localhost --all-databases --single-transaction

-t 僅導出表數據,不導出表結構


免責聲明!

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



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