Dlaczego „LOAD DATA INFILE” jest szybszy niż normalne instrukcje INSERT?


22

Przeczytałem artykuł, w którym wspomniano, że możemy osiągnąć 60 000 wstawień na sekundę za pomocą LOAD DATA IN FILEinstrukcji, która czyta z plików csv i wstawia dane do bazy danych.

Dlaczego ma się różnić od zwykłych wkładek?

EDYCJA:
Zmniejszyłem podróż w obie strony, dzwoniąc tylko do jednego INSERTzdania:

INSERT INTO tblname
VALUES (NULL,2,'some text here0'),(NULL,2,'some text here1')
    ,(NULL,2,'some text here2'),(NULL,2,'some text here3')
    .....,(NULL,2,'some text here3000');

A co z tym?


Napisałem artykuł na temat średnich, porównujących rozszerzone wstawki vs LOAD DATA INFILE: szybkie wkładki z MySQL . Podsumowując: możesz osiągnąć 65% wydajności LOAD DATA INFILEprzy użyciu rozszerzonych płytek. Mam 240 000 wstawek na sekundę na nowoczesnym sprzęcie.
Benjamin

Odpowiedzi:


26

ŁADOWANIE DANYCH PLIK I DŁUGIE WKŁADKI mają swoje wyraźne zalety.

ŁADOWANIE DANYCH INFILE jest przeznaczony do masowego ładowania danych tabeli w jednej operacji wraz z dzwonkami i gwizdkami do wykonywania takich rzeczy jak:

  • Pomijanie linii początkowych
  • Pomijanie określonych kolumn
  • Przekształcanie określonych kolumn
  • Ładowanie określonych kolumn
  • Obsługa duplikatów kluczowych problemów

Parsowanie jest mniejsze

Z drugiej strony, jeśli importujesz tylko 100 wierszy zamiast 1 000 000 wierszy, rozsądne jest rozszerzenie INSERT.

Zauważ, że mysqldump został zaprojektowany wokół rozszerzonych INSERTów w celu przenoszenia projektu tabeli wraz z danymi, ponieważ wykonuje wstrzykiwanie setek lub tysięcy wierszy na INSERT. LOAD DATA INFILE zawsze tworzy fizyczny dichomoty między schematem a danymi.

Z punktu widzenia aplikacji LOAD DATA INFILE jest również bardziej niewrażliwa na zmianę schematu niż rozszerzone WSTAWKI.

Korzystając z opcji LOAD DATA INFILE, można iść w tę i w drugą stronę, co jest dobre, złe i brzydkie. Bez względu na to, jakiej techniki użyjesz, zawsze musisz ustawić rozmiar_wystąpienia_wstaw . Czemu?

Zgodnie z dokumentacją MySQL dotyczącą wielkości pliku luzem_wstaw_bufor:

MyISAM wykorzystuje specjalną pamięć podręczną podobną do drzewa, aby przyspieszyć wstawianie zbiorcze dla WSTAW ... WYBIERZ, WSTAW ... WARTOŚCI (...), (...), ... i ZAŁADUJ DANE INFILE podczas dodawania danych do niepustych stoły Ta zmienna ogranicza rozmiar drzewa pamięci podręcznej w bajtach na wątek. Ustawienie na 0 wyłącza tę optymalizację. Wartość domyślna to 8 MB.

Przez lata widziałem, że klient za klientem nie ustawia tego i pozostawia go na poziomie 8 MB. Następnie, gdy zdecydują się użyć ŁADOWANIA DANYCH NA INFILE lub zaimportować pliki mysqldump, mogą wykryć coś złego. Zwykle zalecam ustawienie tego na umiarkowane 256M. W niektórych przypadkach 512 mln.

Gdy masz już wystarczająco duży bufor INSERT, każda z tych technik jest akademicka i sprowadza się do osobistego wyboru. W aplikacjach, w których luzem wstawiasz tylko 100 rzędów na żądanie, trzymaj się rozszerzonych INSERT.

Mówiąc szczerze, powiedzenie LOAD DATA INFILE jest szybsze, niż normalne instrukcje INSERT, to rodzaj instrukcji ładowanej głównie dlatego, że konfiguracja nie jest brana pod uwagę. Nawet jeśli ustawisz punkt odniesienia między ŁADOWANIEM INFILU DANYCH a rozszerzonymi WSTAWKAMI z odpowiednim rozmiarem_wstaw_buforu_wstaw, nanosekundy zapisane podczas analizowania każdego wiersza mogą przynieść tylko nominalne wyniki w najlepszym wypadku na korzyść ŁADOWANEGO DANYCH.

Śmiało i dodaj to do my.cnf

[mysqld]
bulk_inset_buffer_size=256M

Możesz także ustawić go tylko dla sesji przed uruchomieniem rozszerzonych WSTAWEK

SET bulk_insert_buffer_size= 1024 * 1024 * 256;

AKTUALIZACJA 2012-07-19 14:58 EDT

Aby zachować perspektywę, bufor wstawiania zbiorczego jest użyteczny tylko do ładowania tabel MyISAM, a nie InnoDB. Napisałem nowszy post o ładowaniu zbiorczym InnoDB: ładowanie MySQL z infilu utknęło czekając na dysku twardym


4

Większość systemów zarządzania bazami danych ma funkcję masowego ładowania umożliwiającą szybkie ładowanie dużych ilości danych. Wyciąg INSERTzawiera znaczną ilość bagażu na wyciąg - blokowanie, rozgraniczenie transakcji, sprawdzanie integralności referencyjnej, alokacja zasobów, operacje we / wy, które należy wykonać dla poszczególnych wyciągów.

Operacje wstawiania luzem usprawniają proces, dzięki czemu te elementy mają znacznie, dużo mniej kosztów ogólnych na wiersz. DBMS może masowo ładować rzędy danych o wielkości szybciej niż za pomocą instrukcji insert.


3

Analiza i wykonywanie pojedynczych INSERTinstrukcji niesie ze sobą znacznie większe obciążenie niż dzielenie pliku CSV na kolumny i bezpośrednie ładowanie.

Każda INSERTinstrukcja musi zostać indywidualnie przeanalizowana przez silnik MySQL i sprawdzona pod kątem ważności - zużywa to dodatkowe zasoby procesora i wymaga również więcej podróży w obie strony na serwerze <>. Nie musi się to zdarzyć, gdy ładowanie masowe odbywa się za pośrednictwem LOAD DATA INFILE. Istnieją również optymalizacje, które mogą mieć miejsce podczas LOAD DATA INFILEładowania do pustej tabeli. Zobacz ten link, aby uzyskać więcej informacji.


zobacz część EDYTUJ mojego pytania.
ALH

Zauważ, że podczas korzystania z przygotowanych instrukcji nie ma narzutu.
Benjamin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.