Büyük partiler için ekleme hızları


10

Uygulamamda, INSERT'lerim büyük bir zaman alıyor gibi görünüyor. Bir tabloya eklemek istediğiniz bellek (~ 40-50,000) nesneleri çok sayıda var.

Örnek bir tablo alalım

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

Toplu iş boyutum olarak 3 satır alarak, eklemek için düşünebileceğim yaklaşımlar şunlardır

Yaklaşım 1 - 3 ham kesici uç inşa ve ateş

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

Yaklaşım 2 - Değerleri 1 Sorguda Toplama

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

Yaklaşım 3 - Bu sorguyu 6 kez geçirerek 1 kez tetikleyin

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

Yaklaşım 4 - Hazırlanan bu sorguyu her seferinde 2 parametreyi değiştirerek 3 kez tetikleyin

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

Diğer yaklaşımlar açıktır.

Sorum şu

Tabloda birden çok kesici uç yapmanın en hızlı yolu nedir?

Ben mysql ekleme hızı ve JDBC programlama için bu kılavuzu okudum , ama bir sonuca gelemiyorum.

Benim olayım -

Şu anda benim masamın çoğu 20 sayıdan oluşuyor, bunlardan çoğu sayı, birkaç varchar (60) ve 1 metin sütunu var. Mysql sürüm 5.5. INNODB üzerinde çalışıyor ve Tamsayı birincil anahtarlarında 1 dizin var. Tüm sorgular işlem sırasında çalışır.

Java ile sorgularımı oluşturmak ve sorguları çalıştırmak için Spring JDBC kullanın.

Şu anda Yaklaşım 3'ü izliyorum, sorguyu oluşturmak için gereken süreyi içermeyen boş bir tabloya 20.000 ek için yaklaşık 10 saniye sürüyor.

Olayları perspektif içinde tutmak için, verileri tablodan almak için 100-200 milis alır.

Kaçırdığım bir şey var mı? Uçları nasıl daha hızlı hale getirebilirim?


: Yığın taşması üzerine İlgili soru rewriteBatchedStatements ile MySQL ve JDBC = true
Gord Thompson

Yanıtlar:


3

Taahhütlerinizi toplu hale getirmeyi düşünün. 1024'lük bir parti boyutu iyi bir başlangıç ​​boyutudur. Optimum veriminize ulaşıncaya kadar parti boyutlarını değiştirin.


1

Eklediğiniz hedef DB tablo (lar) ına indeksler düşürdüğünüzü test ettiniz mi veya mümkün mü, bunları daha küçük yığınlı parçalara ekleyin (yukarıda belirtildiği gibi en uygun) ve ardından hedef tablo (lar) da indeksleri yeniden oluşturun tüm ekler tamamlandıktan sonra? Onaylamak için test etmek için yeterince kolay bir şey olabilir.


0

MySQL belgesinden bazı toplu veri yükleme ipuçları yararlı olabilir. https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html

Kesici uç hızını bazı yollarla artırabilirsiniz:

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

Umarım bu yardım!


2
Kısıtlama denetimlerini (benzersiz, yabancı anahtar, ...) kapatıyorsanız, verilerinizin bunları kırmadığından veya veritabanınızın bu noktadan sonra tutarsız bir durumda olduğundan çok emin olun.
David Spillett
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.