日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL批量插入大量数据方法

發(fā)布時間:2024/1/18 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL批量插入大量数据方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在MySQL數(shù)據(jù)庫中,如果要插入上百萬級的記錄,用普通的
insert into

來操作非常不現(xiàn)實(shí),速度慢人力成本高,推薦使用
Load Data

或存儲過程來導(dǎo)入數(shù)據(jù),我總結(jié)了一些方法分享如下,主要基于MyISAM和InnoDB引擎。

InnoDB存儲引擎

首先創(chuàng)建數(shù)據(jù)表(可選),如果有了略過:

> CREATE DATABASE ecommerce; > USE ecommerce; > CREATE TABLE employees (id INT NOT NULL,fname VARCHAR(30),lname VARCHAR(30),birth TIMESTAMP,hired DATE NOT NULL DEFAULT '1970-01-01',separated DATE NOT NULL DEFAULT '9999-12-31',job_code INT NOT NULL,store_id INT NOT NULL)partition BY RANGE (store_id) (partition p0 VALUES LESS THAN (10000),partition p1 VALUES LESS THAN (50000),partition p2 VALUES LESS THAN (100000),partition p3 VALUES LESS THAN (150000),Partition p4 VALUES LESS THAN MAXVALUE);

然后創(chuàng)建存儲過程,其中,

delimiter
命令用來把語句定界符從
;
變?yōu)?br /> //
,不然到
declare var int;
遇上第一個分號MySQL就錯誤停止:

> use ecommerce; > DROP PROCEDURE BatchInser IF EXISTS; > delimiter // -- 把界定符改成雙斜杠 > CREATE PROCEDURE BatchInsert(IN init INT, IN loop_time INT) -- 第一個參數(shù)為初始ID號(可自定義),第二個位生成MySQL記錄個數(shù)BEGINDECLARE Var INT;DECLARE ID INT;SET Var = 0;SET ID = init;WHILE Var < loop_time DOinsert into employees(id, fname, lname, birth, hired, separated, job_code, store_id) values (ID, CONCAT('chen', ID), CONCAT('haixiang', ID), Now(), Now(), Now(), 1, ID);SET ID = ID + 1;SET Var = Var + 1;END WHILE;END;// > delimiter ; -- 界定符改回分號 > CALL BatchInsert(30036, 200000); -- 調(diào)用存儲過程插入函數(shù) 也可以把上面的內(nèi)容(除了語句之前的 > 號)復(fù)制到MySQL查詢框中執(zhí)行。

MyISAM存儲引擎

首先創(chuàng)建數(shù)據(jù)表(可選):

use ecommerce;
CREATE TABLE ecommerce.customer (
id INT NOT NULL,
email VARCHAR(64) NOT NULL,
name VARCHAR(32) NOT NULL,
password VARCHAR(32) NOT NULL,
phone VARCHAR(13),
birth DATE,
sex INT(1),
avatar BLOB,
address VARCHAR(64),
regtime DATETIME,
lastip VARCHAR(15),
modifytime TIMESTAMP NOT NULL,
PRIMARY KEY (id)
) ENGINE = MyISAM ROW_FORMAT = DEFAULT
partition BY RANGE (id) (
partition p0 VALUES LESS THAN (100000),
partition p1 VALUES LESS THAN (500000),
partition p2 VALUES LESS THAN (1000000),
partition p3 VALUES LESS THAN (1500000),
partition p4 VALUES LESS THAN (2000000),
Partition p5 VALUES LESS THAN MAXVALUE
);
再創(chuàng)建存儲過程:

> use ecommerce; > DROP PROCEDURE ecommerce.BatchInsertCustomer IF EXISTS; > delimiter // > CREATE PROCEDURE BatchInsertCustomer(IN start INT,IN loop_time INT)BEGINDECLARE Var INT;DECLARE ID INT;SET Var = 0;SET ID= start;WHILE Var < loop_time DOinsert into customer(ID, email, name, password, phone, birth, sex, avatar, address, regtime, lastip, modifytime) values (ID, CONCAT(ID, '@sina.com'), CONCAT('name_', rand(ID)*10000 mod 200), 123456, 13800000000, adddate('1995-01-01', (rand(ID)*36520) mod 3652), Var%2, 'http:///it/u=2267714161, 58787848&fm=52&gp=0.jpg', '北京市海淀區(qū)', adddate('1995-01-01', (rand(ID)*36520) mod 3652), '8.8.8.8', adddate('1995-01-01', (rand(ID)*36520) mod 3652));SET Var = Var + 1;SET ID= ID + 1;END WHILE;END;// > delimiter ; 調(diào)用存儲過程插入數(shù)據(jù)> ALTER TABLE customer DISABLE KEYS; > CALL BatchInsertCustomer(1, 2000000); > ALTER TABLE customer ENABLE KEYS; 通過以上對比發(fā)現(xiàn)對于插入大量數(shù)據(jù)時可以使用MyISAM存儲引擎,如果再需要修改MySQL存儲引擎可以使用命令:

ALTER TABLE ecommerce ENGINE = MYISAM;

關(guān)于批量插入

提高數(shù)據(jù)插入效率的基本原則如下:
批量插入數(shù)據(jù)的效率比單數(shù)據(jù)行插入的效率高
插入無索引的數(shù)據(jù)表比插入有索引的數(shù)據(jù)表快一些
較短的SQL語句的數(shù)據(jù)插入比較長的語句快
這些因素有些看上去是微不足道的,但是如果插入大量的數(shù)據(jù),即使很小的影響效率的因素也會形成不同的結(jié)果。根據(jù)上面討論的規(guī)則,我們可以就如何快速地加載數(shù)據(jù)得出幾個實(shí)用的結(jié)論。

使用
LOAD DATA
語句要比
INSERT
語句效率高,因?yàn)樗坎迦霐?shù)據(jù)行。服務(wù)器只需要對一個語句(而不是多個語句)進(jìn)行語法分析和解釋。
索引只有在所有數(shù)據(jù)行處理完之后才需要刷新,而不是每處理一行都刷新。

如果你只能使用
INSERT
語句,那就要使用將多個數(shù)據(jù)行在一個語句中給出的格式:
INSERT INTO table_name VALUES(…),(…),…
,這將會減少你需要的語句總數(shù),最大程度地減少了索引刷新的次數(shù)。
根據(jù)上面的結(jié)論,今天又對相同的數(shù)據(jù)和數(shù)據(jù)表進(jìn)行了測試,發(fā)現(xiàn)用
LOAD DATA
速度快了不只是一點(diǎn)點(diǎn),竟然只用了十多分鐘!所以在MySQL需要快速插入大量數(shù)據(jù)時,
LOAD DATA
是你不二的選擇。

順便說一下,在默認(rèn)情況下,
LOAD DATA
語句將假設(shè)各數(shù)據(jù)列的值以制表符(t)分隔,各數(shù)據(jù)行以換行符(n)分隔,數(shù)據(jù)值的排列順序與各數(shù)據(jù)列在數(shù)據(jù)表里的先后順序一致。但你完全可以用它來讀取其他格式的數(shù)據(jù)文件或者按其他順序來讀取各數(shù)據(jù)列的值,有關(guān)細(xì)節(jié)請參照MySQL文檔。

總結(jié)

對于Myisam類型的表,可以通過以下方式快速的導(dǎo)入大量的數(shù)據(jù)。

ALTER TABLE tblname DISABLE KEYS; loading the data ALTER TABLE
tblname ENABLE KEYS;
這兩個命令用來打開或者關(guān)閉MyISAM表非唯一索引的更新。在導(dǎo)入大量的數(shù)據(jù)到一個非空的MyISAM表時,通過設(shè)置這兩個命令,可以提高導(dǎo)入的效率。對于導(dǎo)入大量
數(shù)據(jù)到一個空的MyISAM表,默認(rèn)就是先導(dǎo)入數(shù)據(jù)然后才創(chuàng)建索引的,所以不用進(jìn)行 設(shè)置。

而對于Innodb類型的表,這種方式并不能提高導(dǎo)入數(shù)據(jù)的效率。對于Innodb類型的表,我們有以下幾種方式可以提高導(dǎo)入的效率:因?yàn)镮nnodb類型的表是按照主鍵的順序保存的,所以將導(dǎo)入的數(shù)據(jù)按照主鍵的順序排列,可以有效的提高導(dǎo)入數(shù)據(jù)的效率。如果Innodb表沒有主鍵,那么系統(tǒng)會默認(rèn)創(chuàng)建一個內(nèi)部列作為主鍵,所以如果可以給表創(chuàng)建一個主鍵,將可以利用這個優(yōu)勢提高 導(dǎo)入數(shù)據(jù)的效率。 在導(dǎo)入數(shù)據(jù)前執(zhí)行 SET UNIQUE_CHECKS=0 ,關(guān)閉唯一性校驗(yàn),在導(dǎo)入結(jié)束后執(zhí)行 SET UNIQUE_CHECKS=1 ,恢復(fù)唯一性校驗(yàn),可以提高導(dǎo)入的效率。 如果應(yīng)用使用自動提交的方式,建議在導(dǎo)入前執(zhí)行 SET AUTOCOMMIT=0 ,關(guān)閉自動提交,導(dǎo)入結(jié)束后再執(zhí)行

總結(jié)

以上是生活随笔為你收集整理的MySQL批量插入大量数据方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。