1. 程式人生 > >3.MySQL快速匯入資料LOAD DATA INFILE(帶詳細優化引數)

3.MySQL快速匯入資料LOAD DATA INFILE(帶詳細優化引數)

介紹

LOAD DATA INFILE語句以非常高的速度將文字檔案中的行讀入表中。 LOAD DATA INFILE是SELECT … INTO OUTFILE的補充。要將表中的資料寫入檔案,請使用SELECT … INTO OUTFILE。 要將檔案讀回表中,請使用LOAD DATA INFILE。

基本語法

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [CHARACTER SET charset_name]
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number {LINES | ROWS}]
    [(col_name_or_user_var
        [, col_name_or_user_var] ...)]
    [SET col_name={expr | DEFAULT},
        [, col_name={expr | DEFAULT}] ...]
  • LOW_PRIORITY | CONCURRENT:若指定LOW_PRIORITY,則該LOAD DATA 語句的真正執行將推遲到沒有客戶端在讀取所設計的表時(只對只支援表鎖的引擎有效);

  • LOCAL:若未指定該關鍵字,則說明檔案在MySQL所在機子上,檔案由MySQL伺服器去讀取,此時如果後面指定為檔案路徑為相對路徑,1.如果路徑以./開頭,那麼路徑是相對於MySQL的data目錄的,2.如果路徑不是以./開頭,那麼路徑是相對於預設資料庫的目錄的;若指定了該關鍵字,則說明檔案在客戶端機子上,檔案由客戶端去讀取並通過網路傳送給MySQL伺服器

  • REPLACE | IGNORE :當插入的行遇到UNIQUE欄位重複時,若指定為REPLACE,則用該行替換原來的行;若指定為IGNORE,則忽略改行

  • PARTITION (partition_name,…):將資料插入指定分割槽

  • CHARACTER SET:若不指定字符集,MySQL預設使用character_set_database變數指定的字符集去讀取檔案,若檔案字符集不同,則應指定該關鍵字

  • FIELDS TERMINATED BY:欄位值的分隔符,若不指定則預設為 ‘\t’

  • FIELDS ENCLOSED BY:欄位值的包含字元,若不指定則預設為 ‘’

  • FIELDS ESCAPED BY:欄位值的轉義字元,若不指定則預設為’\’

  • LINES TERMINATED BY:指定行分隔符,若不指定則預設為為系統的預設行分隔符(‘\r\n‘ on windows,’\n’ on linux)

  • LINES STARTING BY:若指定該值為xxx,則MySQL會自動去掉xxx及其前面的字元,若某行不包含xxx,則改行將被忽略,若不指定預設為’’,比如執行以下語句:

      LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test  
        FIELDS TERMINATED BY ','  LINES STARTING BY 'xxx';  
    

    對應的檔案內容為:

      xxx"abc",1  
      something xxx"def",2  
      "ghi",3  
    

    則實際插入的行為(“abc”, 1), (“def”, 2)

  • IGNORE LINES | ROWS:忽略檔案開頭的指定行,比如指定為2,那麼MySQL只會解析並插入第三行及後面的資料

操作

1 修改引數

由於匯入大量資料可能比較佔用系統資源,所以應該先修改引數,保證複製正確快速的執行。由於InnoDB涉及事務所以為了優化插入先將表改為MyISAM然後在轉回InnoDB,這樣操作效率較高。

# 關閉binlog
mysql> SET SQL_LOG_BIN = 0;
# 關閉唯一性檢查
mysql> set unique_checks=0; 
# 關閉外來鍵檢查
mysql> set foreign_key_checks=0; 

# 調整MyISAM引擎引數
mysql> SET SESSION BULK_INSERT_BUFFER_SIZE=256217728;
mysql> SET SESSION MYISAM_SORT_BUFFER_SIZE=256217728;
mysql> SET GLOBAL KEY_BUFFER_SIZE=256217728;
mysql> USE DATABASE;
mysql> ALTER TABLE {table} ENGINE=MyISAM;

# 匯入指令
mysql> LOAD DATA INFILE '/data.txt' INTO TABLE {table} FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES;


# 匯入完畢後進行恢復
mysql> SET SQL_LOG_BIN = 1;
mysql> set unique_checks=1;
mysql> set foreign_key_checks=1; 
mysql> ALTER TABLE {table} ENGINE=InnoDB;

報錯資訊:

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

這個報錯資訊是由於MySQL許可權問題指定了固定目錄執行匯入匯出指令,執行如下指令找到當前的路徑設定

show variables like '%secure%';

avatar

然後修改匯入指令

mysql> LOAD DATA INFILE '/var/lib/mysql-files/data.txt' INTO TABLE {table} FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES;