我需要從一個外部網路服務中匯入資料到我的MySQL(5.7)資料庫。 問題是,我需要將資料分成若干個表。例如,我有以下表格
CREATE TABLE a (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100)
);
創建 TABLE b (
id INT PRIMARY KEY AUTO_INCREMENT,
a_id INT,
name VARCHAR(100)
);
現在我必須為表a中的一條記錄向表b插入多條記錄(1:n)。 由于在插入前我不知道表a的id,唯一的方法是在表a中插入一行,得到最后的id,然后將所有連接的條目插入表b。
但是,當我逐行插入時,我的資料庫非常慢。如果我在表a上批量插入約1000行(只是為了測驗而不填充表b),它就會快得令人難以置信(不到3分鐘)
我想必須在表a上插入一行,并獲得最后的id,然后將所有連接的條目插入表b。
我想一定有一個解決方案,我可以加快我的匯入速度。
感謝您的幫助
uj5u.com熱心網友回復:
我推測你是用一種編程語言來驅動你的插入。你需要能夠對這個操作序列進行編程。
首先,你需要使用這個序列將一行放入a,將從屬行放入b。它使用LAST_INSERT_ID()來處理a_id。這比查詢表以找到正確的ID值要快得多,也穩健得多。
INSERT INTO a (name) VALUES ('Claus'/span>) 。
SET @a_id = LAST_INSERT_ID()。
INSERT INTO b (a_id, name) VALUES (@a_id, 'von')。
INSERT INTO b (a_id, name) VALUES (@a_id, 'B?nnhoff') 。
訣竅是在會話變數@a_id中捕獲a.id的值,然后在每個依賴的INSERT中重復使用它。
第二,你應該牢記這一點。 INSERTs很便宜,但是transaction COMMITs很昂貴。這是因為MySQL(實際上是InnoDB)在COMMIT之前實際上并不更新表。除非你明確地管理你的事務,否則DBMS使用了一個稱為 "自動提交 "的功能,它立即提交每個INSERT(或UPDATE或DELETE)。
更少的事務可以讓你獲得更好的速度。因此,為了提高批量加載性能,你希望將100個左右的INSERT捆綁到一個事務中。(你可以這樣做:
START TRANSACTION; /* start an insertion bundle */
INSERT INTO a (name) VALUES ('Claus') 。
SET @a_id = LAST_INSERT_ID()。
INSERT INTO b (a_id, name) VALUES (@a_id, 'von')。
INSERT INTO b (a_id, name) VALUES (@a_id, 'B?nnhoff') 。
INSERT INTO a (name) VALUES ('Oliver')。
SET @a_id = LAST_INSERT_ID()。
INSERT INTO b (a_id, name) VALUES (@a_id, 'Jones' /span>) 。
... 更多的INSERT操作 ...
INSERT INTO a (name) VALUES ('Jeff')。
SET @a_id = LAST_INSERT_ID()。
INSERT INTO b (a_id, name) VALUES (@a_id, 'Atwood' /span>);
COMMIT; /* commit the bundle */。
START TRANSACTION; /* start the next bundle */
INSERT INTO a (name) VALUES ('Joel') 。
SET @a_id = LAST_INSERT_ID()。
INSERT INTO b (a_id, name) VALUES (@a_id, 'Spolsky' />) 。
... 更多的INSERT操作 ...
COMMIT; /* 完成捆綁 */
(除了LAST_INSERT_ID()之外,所有這些都可以在任何基于SQL的RDBMS上作業。每個RDBMS都有自己的處理ID的方式。(
)轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/333996.html
標籤:
