2010-09-30 7 views
7

Próbuję uzyskać lepsze informacje na temat szybkości wstawiania i wzorców wydajności w mysql dla niestandardowego produktu. Mam dwie tabele, do których ciągle dołączam nowe wiersze. Te dwie tabele są zdefiniowane następująco:Spowolnienie prędkości wstawiania w miarę wzrostu tabeli w mysql

CREATE TABLE events (
added_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
id BINARY(16) NOT NULL, 
body MEDIUMBLOB, 
UNIQUE KEY (id)) ENGINE InnoDB; 

CREATE TABLE index_fpid (
fpid VARCHAR(255) NOT NULL, 
event_id BINARY(16) NOT NULL UNIQUE, 
PRIMARY KEY (fpid, event_id)) ENGINE InnoDB; 

I zachować wstawianie nowych obiektów do obu tabel (dla każdego nowego obiektu, wstawić odpowiednie informacje do obu tabel w jednej transakcji). Na początku dostaję około 600 wstawień/sekundę, ale po ~ 30000 rzędach dostaję znaczne spowolnienie (około 200 wstawień/s), a następnie spowolnienie, ale nadal zauważalne spowolnienie.

Widzę, że wraz z rosnącą tabelą liczba oczekujących na IO jest coraz wyższa. Moją pierwszą myślą była pamięć pobrana przez indeks, ale te są wykonywane na maszynie wirtualnej, która ma 768 Mb i jest przeznaczona wyłącznie do tego zadania (2/3 pamięci nie jest używana). Ponadto trudno jest zobaczyć 30000 wierszy zajmujących tak dużo pamięci, a nawet więcej, tylko indeksy (cały katalog danych mysql < 100 Mb). Aby to potwierdzić, przydzieliłem bardzo mało pamięci do maszyny wirtualnej (64 Mb), a wzór spowolnienia jest prawie identyczny (tj. Spowolnienie pojawia się po tej samej liczbie wstawień), więc podejrzewam pewne problemy z konfiguracją, zwłaszcza, że ​​jestem stosunkowo nowy bazy danych.

Wzór wygląda następująco: alt text

mam samodzielne Pythona skrypt, który odtwarza ten problem, że mogę udostępnić jeśli to pomocne.

Konfiguracja:

  • Ubuntu 10.04, 32 bity działające na KVM, 760 Mb przypisane do niego.
  • Mysql 5.1 z konfiguracją skrzynki z oddzielnych plików dla tabel

[EDIT]

Dziękuję bardzo Eric Holmberg, że się udało. Oto wykresy po naprawieniu wartości innodb_buffer_pool_size do rozsądnej wartości: alt text

+0

Problem z możliwością zapisu na dysku wirtualnym lub innym. –

+0

Nie jestem pewien, czy rozumiem, co masz na myśli: Rozumiem, że potrzeba czasu na zapisanie na dysku, ale to nie wyjaśnia spowolnienia w miarę wzrostu tabeli. –

Odpowiedz

8

Edytuj plik /etc/mysql/my.cnf i upewnij się, że alokujesz wystarczającą ilość pamięci do puli buforów InnoDB. Jeśli jest to serwer dedykowany, prawdopodobnie użyjesz nawet 80% pamięci systemowej.

# Provide a buffer pool for InnoDB - up to 80% of memory for a dedicated database server 
innodb_buffer_pool_size=614M 

The kluczy podstawowych są B Drzewa więc wstawia zawsze będzie O (logn) czas i gdy zabraknie pamięci podręcznej, zaczną swapping jak szalony. Gdy tak się stanie, prawdopodobnie będziesz chciał podzielić dane na partycje, aby przyspieszyć wstawianie. Zobacz http://dev.mysql.com/doc/refman/5.1/en/partitioning.html, aby uzyskać więcej informacji na temat partycjonowania.

Powodzenia!

+0

To było to, dziękuję bardzo. Będę aktualizować wykresy, aby pokazać różnicę, jest to dość uderzające. Dzięki za podpowiedź partycjonowania: zaglądałem już do partycji, ale nie chciałem tam pojechać bez uprzedniego zrozumienia tego problemu. –

+2

Dziękuję za dalszą aktualizację wykresów - drugi zestaw wygląda świetnie! –

1

Twoje indeksy mogą po prostu zostać poddane analizie i zoptymalizowane podczas wstawiania, stopniowo znikają z formy. Inną opcją jest oczywiście całkowite wyłączenie indeksów podczas ich późniejszego wstawiania i przebudowy, co powinno zapewnić bardziej stałą wydajność.

Great link about insert speed.

ANALYZE. OPTIMIZE

+0

Istnieją tylko dwa indeksy - klucz podstawowy i unikalne ograniczenie. Oba wymuszają unikalne wartości. O ile nie ma skasowania, nie ma nic do utrzymania. –

+0

Nie sądzę, abym mógł wyłączyć indeks (w mojej aplikacji muszę udostępnić wstawki, gdy tylko zostaną napisane, a wstawki przychodzą "w czasie rzeczywistym", to nie jest przetwarzanie wsadowe). –

+0

Ufam ci OMG, jeśli mówisz, że tak jest, czekam z niecierpliwością na twoją odpowiedź, abym mógł się uczyć. –

0

Sprawdzanie, czy wstawienie nie narusza ograniczenia klucza, zajmuje trochę czasu, a ten czas rośnie, gdy tabela staje się większa. Jeśli zależy Ci na większej wydajności, użycie funkcji LOAD DATA INFILE znacznie poprawi prędkość wkładania.

+0

Oczekiwano wstawienia spowolnienia w miarę wzrostu tabeli (ze względu na koszt dziennika (N) aktualizacji indeksu). Ale spowolnienie spowodowane jest przez zwiększenie IO, jeśli wierzę w iowait%, i to nieoczekiwane (ponieważ mam zestaw danych, który jest wystarczająco mały, aby zmieścić się całkowicie w pamięci). Ponadto moje wykresy nie wykazują spowalniania dziennika (N). –

+0

To dość rzadko, że cały zestaw danych zmieści się w pamięci, ale cieszę się, że problem został rozwiązany. "LOAD DATA INFILE" nadal pokazuje dalsze ulepszenia wydajności, jeśli Twoje wymagania są takie. –

Powiązane problemy