Chèn tốc độ cho các lô lớn


10

Trong ứng dụng của tôi, các INSERT của tôi dường như chiếm một phần lớn thời gian. Tôi có một số lượng lớn các đối tượng trong bộ nhớ (~ 40-50.000) mà tôi muốn chèn vào một bảng.

Hãy lấy một bảng mẫu

CREATE TABLE bill (
id BIGINT(20) PRIMARY KEY,
amount INT(11) DEFAULT 0,
bill_date DATETIME DEFAULT NOW(),
INDEX (bill_date)
) ENGINE=InnoDB

Lấy 3 hàng làm cỡ lô của tôi, sau đây là các cách tiếp cận tôi có thể nghĩ đến để chèn

Cách tiếp cận 1 - xây dựng và bắn 3 chèn thô

INSERT INTO bill (amount, bill_date) VALUES (10, '2012-01-01 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (20, '2012-01-02 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (40, '2013-02-05 00:00:00');

Cách tiếp cận 2 - ghép các giá trị thành 1 truy vấn

INSERT INTO bill (amount, bill_date) VALUES 
(10, '2012-01-01 00:00:00'),
(20, '2012-01-02 00:00:00'),
(40, '2013-02-05 00:00:00');

Cách tiếp cận 3 - thực hiện truy vấn này 1 lần qua 6 tham số

INSERT INTO bill (amount, bill_date) VALUES 
(?, ?), (?, ?), (?, ?);

Cách tiếp cận 4 - Bắn truy vấn đã chuẩn bị này 3 lần thay đổi 2 tham số mỗi lần

INSERT INTO bill (amount, bill_date) VALUES (?, ?);

Bất kỳ phương pháp khác đều được chào đón.

Câu hỏi của tôi là

Cách nhanh nhất để thực hiện nhiều chèn trong một bảng là gì?

Tôi đã đọc liên kết này về tốc độ chèn mysqlhướng dẫn này về lập trình JDBC , nhưng tôi không thể đưa ra kết luận.

Trường hợp của tôi -

Hiện tại bảng của tôi có ~ 20 cột, hầu hết là các số, với một vài cột varchar (60) và 1 cột văn bản. Phiên bản Mysql 5.5. Chạy trên INNODB và có 1 chỉ mục trên các khóa chính Integer. Tất cả các truy vấn chạy trong giao dịch.

Tôi xây dựng các truy vấn của mình từ Java và sử dụng Spring JDBC để chạy các truy vấn.

Tôi hiện đang theo Cách tiếp cận 3, Mất khoảng 10 giây để 20.000 lần chèn vào một bảng trống, không bao gồm thời gian cần thiết để tạo truy vấn.

Để giữ mọi thứ trong phối cảnh, phải mất 100-200 mili để lấy dữ liệu từ bảng.

Có cái gì tôi đang thiếu? Làm thế nào để tôi thực hiện chèn nhanh hơn?


Câu hỏi liên quan về Stack Overflow: MySQL và JDBC với RewriteBatchedStatements = true
Gord Thompson

Câu trả lời:


3

Xem xét việc thực hiện các cam kết của bạn. Một kích thước lô 1024 là một kích thước bắt đầu tốt. Thay đổi kích thước lô cho đến khi bạn đạt được thông lượng tối ưu của bạn.


1

Bạn đã thử nghiệm hay có thể thả các chỉ mục trên (các) bảng DB đích mà bạn đang chèn vào, chèn chúng vào các khối nhỏ hơn (tối ưu như đã chỉ ra ở trên), sau đó xây dựng lại các chỉ mục trên (các) bảng đích một khi tất cả các chèn được hoàn thành? Có thể là một cái gì đó đủ dễ dàng để kiểm tra để xác nhận.


0

Một số mẹo tải dữ liệu số lượng lớn từ tài liệu mysql có thể hữu ích. https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html

Bạn có thể tăng tốc độ chèn bằng một số cách:

- turn off autocommit
- turn off unique check
- turn off foreign check

Hy vọng điều này giúp đỡ !


2
Nếu tắt kiểm tra ràng buộc (duy nhất, khóa ngoại, ...) thì rất chắc chắn rằng dữ liệu của bạn không phá vỡ chúng hoặc cơ sở dữ liệu của bạn ở trạng thái không nhất quán từ thời điểm đó trở đi.
David Spillett
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.