Masukkan Kecepatan untuk kumpulan besar

10

Dalam aplikasi saya, INSERT saya tampaknya mengambil sebagian besar waktu. Saya memiliki sejumlah besar objek dalam memori (~ 40-50.000) yang ingin saya masukkan ke dalam tabel.

Mari kita ambil contoh tabel

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

Mengambil 3 baris sebagai ukuran batch saya, berikut ini adalah pendekatan yang bisa saya pikirkan untuk memasukkan

Pendekatan 1 - bangun dan tembak 3 sisipan mentah

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');

Pendekatan 2 - mengelompokkan nilai-nilai menjadi 1 kueri

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');

Pendekatan 3 - jalankan kueri ini 1 kali melewati 6 parameter

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

Approach 4 - Fire query ini disiapkan 3 kali mengubah 2 parameter setiap kali

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

Semua pendekatan lain dipersilakan.

Pertanyaanku adalah

Apa cara tercepat untuk membuat banyak sisipan dalam sebuah tabel?

Saya telah membaca tautan ini pada kecepatan insert mysql dan panduan ini untuk pemrograman JDBC , tapi saya tidak bisa sampai pada kesimpulan.

Kasus saya -

Saat ini meja saya memiliki ~ 20 kolom, yang sebagian besar adalah angka, dengan beberapa kolom varchar (60) dan 1. Mysql versi 5.5. Berjalan di INNODB dan memiliki 1 indeks pada kunci utama Integer. Semua kueri berjalan dalam transaksi.

Saya membangun kueri saya dari Jawa dan menggunakan Spring JDBC untuk menjalankan kueri.

Saat ini saya mengikuti Pendekatan 3, Butuh sekitar 10 detik untuk 20.000 sisipan ke tabel kosong, tidak termasuk waktu yang diperlukan untuk membuat kueri.

Untuk menjaga hal-hal dalam perspektif, butuh 100-200 milidetik untuk mengambil data dari tabel.

Apakah ada sesuatu yang saya lewatkan? Bagaimana cara membuat sisipan lebih cepat?

Aditya
sumber
Pertanyaan terkait tentang Stack Overflow: MySQL dan JDBC dengan rewriteBatchedStatements = true
Gord Thompson

Jawaban:

3

Pertimbangkan untuk mengumpulkan komitmen Anda. Ukuran batch 1024 adalah ukuran awal yang baik. Ubah ukuran batch hingga Anda mencapai throughput optimal Anda.

Rick Ryker
sumber
1

Sudahkah Anda menguji atau apakah mungkin untuk menjatuhkan indeks pada tabel DB tujuan di mana Anda memasukkan, memasukkannya ke dalam potongan batch yang lebih kecil (optimal seperti yang ditunjukkan di atas), dan kemudian membangun kembali indeks pada tabel tujuan (s) setelah semua sisipan selesai? Mungkin sesuatu yang cukup mudah untuk diuji untuk mengonfirmasi.

Pimp Juice
sumber
0

Beberapa kiat memuat data massal dari dokumen mysql mungkin bermanfaat. https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html

Anda dapat meningkatkan kecepatan memasukkan dengan beberapa cara:

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

Semoga bantuan ini!

Luke Nguyen
sumber
2
Jika menonaktifkan pemeriksaan kendala (unik, kunci asing, ...) sangat sangat yakin bahwa data Anda tidak merusaknya atau database Anda dalam keadaan tidak konsisten sejak saat itu dan seterusnya.
David Spillett