Jak poprawić wydajność MySQL INSERT i UPDATE?

14

To pytanie można prawdopodobnie zadać również na StackOverflow, ale najpierw spróbuję tutaj ...

Wydajność instrukcji INSERT i UPDATE w naszej bazie danych wydaje się obniżać i powodować niską wydajność w naszej aplikacji internetowej.

Tabele to InnoDB, a aplikacja wykorzystuje transakcje. Czy są jakieś łatwe poprawki, które mogę przyspieszyć?

Myślę, że możemy mieć problemy z blokowaniem, jak mogę się dowiedzieć?

mmattax
źródło
Lepiej na dba.stackexchange.com
Pacerier

Odpowiedzi:

25
  1. Sprawdź, czy Twój sprzęt i system operacyjny są poprawnie skonfigurowane i dostrojone:

    • Źródło problemu (użycie procesora / IO / pamięci / wymiany). Czy masz dużo procesorów IOP? Czy procesor jest załadowany? Jeśli masz dużo odczytanych procesorów IOP, prawdopodobnie nie masz wystarczająco dużej puli buforów InnoDB. Jeśli procesor jest załadowany, prawdopodobnie zapytania wykonują pełne skanowanie tabeli zamiast używania odpowiednich indeksów.
    • Konfiguracja dysku / RAID / LVM. W niektórych określonych konfiguracjach rozłożenie LVM może przynieść korzyści poprzez wyrównanie obciążenia dysku (bez sprzętowego RAID, podłączonych wiele LUNS)
    • Harmonogram we / wy: jeśli masz dobry sprzętowy kontroler RAID, prawdopodobnie noop jest najlepszy. RedHat wykonał kilka testów i powiedzieli, że dla Oracle (i innych DB) CFQ jest najlepszym wyborem. Musisz uruchomić kilka testów porównawczych (takich jak tpc-c lub tpc-e) i wybrać, co jest najlepsze dla twojego sprzętu.
    • Dobry system plików - ext3 nie działa dobrze w przypadku obciążeń specyficznych dla bazy danych. Lepiej jest XFS lub OCFS2. Potrzebujesz jeszcze kilku testów.
    • Uważaj, jeśli twój system używa wymiany. Korzystanie z zamiany zmniejsza wydajność mysql .
  2. Sprawdź, czy instancja MySQL / InnoDB jest odpowiednio dostrojona:

    • wielkość puli buforów - buforuj strony danych w pamięci
    • innodb_flush_method = O_DIRECT - unikaj podwójnego buforowania IO
    • zwiększ rozmiar pliku dziennika InnoDB - w przypadku intensywnego obciążenia zapisu może to poprawić wydajność. Pamiętaj jednak: większy rozmiar pliku dziennika oznacza dłuższe odzyskiwanie po awarii. Czasem w godzinach !!!
    • innodb_flush_log_at_trx_commit = 0 lub 2 - Jeśli nie martwisz się o ACID i możesz stracić transakcje w ciągu ostatniej sekundy lub dwóch.
    • key_buffer_size - bardzo ważny dla MyISAM, ale służy do tymczasowych tabel dysku.
    • Obserwuj swój status INNODB
  3. Przeanalizuj swoje obciążenie - złap wszystkie zapytania w dzienniku spowolnienia i uruchom na nim mk-query-digest. Możesz złapać wszystkie zapytania za pomocą tcpdump i maatkit
    • Jakie zapytania zajmują najwięcej czasu serwera?
    • Czy są tworzone tabele tymczasowe, szczególnie duże tabele tymczasowe?
    • Dowiedz się, jak korzystać z wyjaśnienia
    • Czy Twoja aplikacja korzysta z transakcji? Po uruchomieniu zapytań z autocommit = 1 (domyślnie MySQL), każde zapytanie wstawiania / aktualizacji rozpoczyna nową transakcję, co powoduje pewne obciążenie. Jeśli to możliwe, lepiej wyłączyć automatyczne zatwierdzanie (w sterowniku Python automatyczne zatwierdzanie sterownika MySQL jest domyślnie wyłączone) i ręcznie wykonać zatwierdzenie po wykonaniu wszystkich modyfikacji.
    • Czy twoja aplikacja tworzy w pętli serie wstawek do tego samego stołu? Load data infilepolecenie jest znacznie szybsze dla serii wstawek.
    • Pamiętaj: select count(*) from table;jest znacznie wolniejszy dla innodb niż dla myisam.
    • Jakie typy zapytań INSERT / UPDATE zajmują najwięcej czasu serwera? Jak można je zoptymalizować?
    • Sprawdź, czy twoja baza danych ma odpowiednie indeksy i dodaj je, jeśli to konieczne.

W naszym środowisku mieliśmy sytuację, że jeden typ zapytań o aktualizację był powolny. Szacowany czas na zakończenie zadania wsadowego wynosił 2 dni !!! Po przeanalizowaniu dziennika spowolnienia stwierdzamy, że ten typ zapytania o aktualizację potrzebuje 4 sekund na zakończenie. Zapytanie wyglądał tak: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. Po przekonwertowaniu zapytania aktualizacyjnego na wybrane zapytanie i uruchomieniu wyjaśnienia na tym wybranym zapytaniu stwierdzamy, że ten typ zapytania nie używa indeksu. Po utworzeniu odpowiedniego indeksu skróciliśmy czas wykonywania zapytania o aktualizację do milisekund, a całe zadanie zakończyło się w mniej niż dwie godziny.

Kilka przydatnych linków:

sumar
źródło
Przed tym wszystkim sprawdź wskaźniki. Degradujące SMELLY takie jak „w miarę powiększania się tabel, ponieważ nie mamy indeksów”.
TomTom
5

Dzięki domyślnej konfiguracji innoDB będziesz ograniczony do tego, jak szybko możesz zapisywać i opróżniać transakcje na dysk. Jeśli możesz sobie poradzić z utratą małego ACID, eksperymentuj z innodb_flush_log_at_trx_commit. Ustaw na 0, aby zapisywać i opróżniać dziennik na dysk co sekundę. Ustaw na 1 (domyślnie), aby pisać i opróżniać przy każdym zatwierdzeniu. Ustaw na 2, aby zapisywać do pliku dziennika po każdym zatwierdzeniu, ale opróżniaj tylko raz na sekundę.

Jeśli poradzisz sobie z utratą 1 transakcji, może to być świetny sposób na znaczną poprawę wydajności zapisu.

Zwróć także uwagę na to, co robią twoje dyski. RAID 10> RAID 5 dla zapisów kosztem dodatkowego dysku.

tomchuk
źródło
1

Problemy z blokowaniem zostaną przeanalizowane przez stany połączenia w show full processlist;

Przeczytaj przez my.cnf dokumentację i MySQL. Opcje konfiguracji są bardzo dobrze udokumentowane.

Ogólnie rzecz biorąc, chcesz przetworzyć jak najwięcej w pamięci. W przypadku optymalizacji zapytań oznacza to unikanie tabel tymczasowych. Prawidłowe stosowanie indeksów.

Strojenie będzie dostosowane do preferowanego silnika bazy danych i architektury aplikacji. Istnieją znaczne zasoby wcześniej istniejące wyszukiwanie w Internecie.

Warner
źródło
0

InnoDB to całkiem niezły silnik. Jednak w dużej mierze zależy od „dostrojenia”. Jedną rzeczą jest to, że jeśli twoje wstawki nie są w porządku rosnącej liczby kluczy podstawowych, innoDB może potrwać nieco dłużej niż MyISAM. Można to łatwo pokonać, ustawiając większy rozmiar innodb_buffer_pool_size. Sugeruję ustawienie 60–70% całkowitej pamięci RAM. Obecnie używam 4 takich serwerów w produkcji, wstawiam około 3,5 miliona wierszy na minutę. Mają już blisko 3 terabajty. InnoDB musiało tak być ze względu na wysoce współbieżne wstawki. Istnieją dalsze sposoby na przyspieszenie wkładek. A niektóre z nich przeprowadziłem testy porównawcze.

Ajay Divakaran
źródło
0

Jak rozwiązywać problemy z wstawieniem i aktualizacją wydajności w MySQL w aplikacji sieci Web, po prostu wyłączając automatyczne zatwierdzanie i zatwierdzanie zmian raz w java. Zgodnie z sugestią w dokumentacji mysql.

Dokumenty MySQL

Jatinder
źródło