Wstaw prędkości dla dużych partii

10

W mojej aplikacji wydaje się, że moje WSTAWKI zajmują sporo czasu. Mam w pamięci dużą liczbę obiektów (~ 40-50 000), które chcę wstawić do tabeli.

Weźmy przykładową tabelę

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

Biorąc 3 rzędy za mój rozmiar partii, poniżej są podejścia, które mógłbym wymyślić do wstawiania

Podejście 1 - zbuduj i wystrzel 3 surowe wkładki

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

Podejście 2 - połączenie wartości w 1 zapytanie

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

Podejście 3 - uruchom to zapytanie 1 raz, przekazując 6 parametrów

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

Podejście 4 - Uruchom to przygotowane zapytanie 3 razy, zmieniając za każdym razem 2 parametry

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

Wszelkie inne podejścia są mile widziane.

Moje pytanie brzmi

Jaki jest najszybszy sposób na wykonanie wielu wstawek w tabeli?

Przeczytałem ten link o szybkości wstawiania mysql i ten przewodnik po programowaniu JDBC , ale nie jestem w stanie dojść do wniosku.

Mój przypadek -

Obecnie moja tabela ma ~ 20 kolumn, z których większość to liczby, z kilkoma varcharami (60) i 1 kolumną tekstową. Wersja MySQL 5.5. Działa na INNODB i ma 1 indeks na kluczach głównych Integer. Wszystkie zapytania uruchamiane są w transakcji.

Moje zapytania tworzę z Javy i używam Spring JDBC do uruchamiania zapytań.

Obecnie postępuję zgodnie z Podejściem 3, 20 000 wstawek do pustej tabeli zajmuje około 10 sekund, nie licząc czasu potrzebnego na zbudowanie zapytania.

Aby zachować perspektywę, potrzeba 100-200 milisów, aby pobrać dane z tabeli.

Czy czegoś brakuje? Jak mogę przyspieszyć wstawianie?

Aditya
źródło
Podobne pytanie dotyczące przepełnienia stosu: MySQL i JDBC z rewriteBatchStatements = true
Gord Thompson

Odpowiedzi:

3

Rozważ podzielenie swoich zobowiązań. Wielkość partii 1024 to dobry rozmiar początkowy. Zmieniaj rozmiary partii, aż osiągniesz optymalną wydajność.

Rick Ryker
źródło
1

Czy przetestowałeś lub czy byłoby możliwe upuszczenie indeksów w docelowej tabeli (tabelach) DB, do której wstawiasz, wstaw je do mniejszych porcji (optymalne, jak wskazano powyżej), a następnie odbuduj indeksy w tabelach docelowych kiedy wszystkie wkładki są gotowe? Może być czymś wystarczająco łatwym do przetestowania, aby potwierdzić.

Pimp Juice IT
źródło
0

Przydatne mogą być niektóre porady dotyczące ładowania danych zbiorczych z dokumentu mysql. https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html

Szybkość wstawiania można zwiększyć na kilka sposobów:

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

Mam nadzieję, że to pomoże !

Luke Nguyen
źródło
2
Jeśli wyłączysz sprawdzanie ograniczeń (unikalny, klucz obcy, ...), bądź bardzo pewny, że twoje dane ich nie złamią lub baza danych będzie od tego momentu niespójna.
David Spillett,