Wydajność Mysql na tabeli 6 milionów wierszy

Pewnego dnia podejrzewam, że będę musiał nauczyć się hadoop i przenieść wszystkie te dane do niestrukturalnej bazy danych, ale jestem zaskoczony, że wydajność spada tak znacząco w tak krótkim czasie.

Mam tabelę mysql z prawie 6 milionami wierszy. Robię bardzo proste zapytanie na tej tabeli i wierzę, że mam wszystkie poprawne indeksy na miejscu.

Zapytanie to

SELECT date, time FROM events WHERE venid='47975' AND date>='2009-07-11' ORDER BY date

The explain zwraca

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  updateshows     range   date_idx    date_idx    7   NULL    648997  Using where

Więc używam poprawnego indeksu o ile można powiedzieć, ale to zapytanie trwa 11 sekund, aby uruchomić.

Baza danych to MyISAM, a phpMyAdmin mówi, że tabela To 1.0 GiB.

Jakieś pomysły?

Edytowane: Date_idx indeksuje zarówno kolumny date, jak i venid. Czy powinny to być dwa oddzielne indeksy?

Author: JulianR, 2009-07-12

4 answers

Chcesz się upewnić, że zapytanie będzie używać tylko indeksu, więc upewnij się, że indeks obejmuje wszystkie zaznaczone pola. Ponadto, ponieważ jest to zapytanie zakresu, musisz mieć venid jako pierwszy w indeksie, ponieważ jest pytany jako stała. Chciałbym zatem utworzyć i indeksować w ten sposób:

ALTER TABLE events ADD INDEX indexNameHere (venid, date, time);

W tym indeksie wszystkie informacje potrzebne do wypełnienia zapytania znajdują się w indeksie. Oznacza to, że, miejmy nadzieję, silnik magazynowy jest w stanie pobrać informacji bez szukania wewnątrz samej tabeli. Jednak MyISAM może nie być w stanie tego zrobić, ponieważ nie przechowuje danych w liściach indeksów, więc możesz nie uzyskać pożądanego wzrostu prędkości. W takim przypadku spróbuj utworzyć kopię tabeli i użyj silnika InnoDB na kopii. Powtórz tam te same kroki i sprawdź, czy masz znaczny wzrost prędkości. InnoDB przechowuje wartości pól w liściach indeksu i pozwala na pokrycie indeksy.

Teraz, mam nadzieję, że zobaczysz, co następuje, gdy wyjaśnisz zapytanie:

mysql> EXPLAIN SELECT date, time FROM events WHERE venid='47975' AND date>='2009-07-11' ORDER BY date;

id  select_type table  type  possible_keys        key       [..]  Extra
1   SIMPLE   events range date_idx, indexNameHere indexNameHere   Using index, Using where
 41
Author: PatrikAkerstrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-11 21:39:41

Spróbuj dodać klucz, który obejmuje venid i date (lub odwrotnie, lub oba...)

 2
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-11 20:55:28

Wyobrażam sobie, że stół z 6-metrowym wierszem powinien być zoptymalizowany całkiem normalnymi technikami.

Zakładam, że masz dedykowany serwer bazy danych i ma on rozsądną ilość pamięci ram (powiedzmy minimum 8G).

Będziesz chciał upewnić się, że dostrojony mysql do efektywnego wykorzystania pamięci ram. Jeśli używasz 32-bitowego systemu operacyjnego, nie rób tego. jeśli używasz MyISAM, dostosuj bufor klawiszy, aby używał znaczącej proporcji, ale nie zbyt dużej, pamięci ram.

In any case you want to run powtarzające się testy wydajności na sprzęcie produkcyjnym.

 2
Author: MarkR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-11 21:53:40

Spróbuj umieścić indeks na kolumnie venid.

 1
Author: Lucas Jones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-11 20:55:37