Przejdź do treści

MySQL – optymalizacja i wydajność

O pracy MySQL DBA – przemyślenia administratora

Archiwa

Archiwa z daty Wrzesień, 2010

Na temat tego, jak skonfigurować replikację w MySQL można znaleźć w internecie sporo informacji. Z resztą, na tym blogu taki krótki opis także się pojawi. Tym razem jednak wspomnę kilka słów o tym, jak działa mechanizm replikacji w MySQL. Replikacja to jeden z najprostszych sposobów aby zapewnić sobie skalowalność aplikacji. Ogólna idea jest taka, że mamy jeden serwer – master, na którym wykonywane są wszystkie zapytania modyfikujące dane. Modyfikacje te przenoszone są przez replikację na drugi serwer (albo serwery, może ich być więcej) – slave. W efekcie mamy dwie, teoretycznie identyczne kopie bazy danych, na których możemy wykonywać zapytania typu SELECT. Jak to wygląda w praktyce?

czytaj dalej…

Podczas rutynowych prac natknąłem się na bardzo ciekawe zapytanie o następującym planie wykonania:

+----+--------------------+-----------------+------+---------------+------+---------+------+-------+----------------------------------------------+
| id | select_type        | table           | type | possible_keys | key  | key_len | ref  | rows  | Extra                                        |
+----+--------------------+-----------------+------+---------------+------+---------+------+-------+----------------------------------------------+
|  1 | PRIMARY            | <derived2>      | ALL  | NULL          | NULL | NULL    | NULL |   185 |                                              |
|  2 | DERIVED            | tab1            | ALL  | NULL          | NULL | NULL    | NULL |  2869 | Using where; Using temporary; Using filesort |
|  2 | DERIVED            | tab2            | ALL  | NULL          | NULL | NULL    | NULL |  2869 |                                              |
|  2 | DERIVED            | tab3            | ALL  | NULL          | NULL | NULL    | NULL |  2869 |                                              |
|  2 | DERIVED            | tab4            | ALL  | NULL          | NULL | NULL    | NULL | 10483 |                                              |
|  4 | DEPENDENT SUBQUERY | tab5            | ALL  | NULL          | NULL | NULL    | NULL |  5613 | Using where                                  |
|  3 | DEPENDENT SUBQUERY | tab6            | ALL  | NULL          | NULL | NULL    | NULL |  2311 | Using where                                  |
+----+--------------------+-----------------+------+---------------+------+---------+------+-------+----------------------------------------------+
7 rows in set (2 min 12.76 sec)

Przyznam, że jest to swojego rodzaju rekord. Sam EXPLAIN wykonywał się kilka minut, zapytanie analizowało prawie 7 milionów rekordów. Co lepsze, zapytanie to do poindeksowania było banalne – SELECT z jednym podzapytaniem, w którego skład wchodziły OUTER JOINy. Skoro na załączonym przykładzie widać, że indeksowanie JOINów nie jest rzeczą oczywistą, to popatrzmy jak to można zrobić.
czytaj dalej…

MySQL 5.5.6 stało się oficjalnie Release Candidate dla nowej stabilnej wersji MySQL. Polecam ściągnięcie nowej wersji i zapoznanie się z tym, co już niedługo stanie się standardem w MySQL – InnoDB jako domyślny silnik bazodanowy, PERFORMANCE_SCHEMA, lepsza wydajność przy większej ilości jednoczesnych połączeń.

Co pewien czas spotykam się z sytuacją, gdy serwer bazodanowy, a konkretnie jego procesor, przeciążany jest przez zapytania typu:

UPDATE jakastabela SET cokolwiek = '4' WHERE kolumna1 = '10' AND kolumna2 = '20';

Dlaczego takie zapytanie tak bardzo obciąża CPU? Przecież zapytanie typu UPDATE to modyfikacja danych, czyli operacja dyskowa? Co tu robi procesor? Przyczyna jest zazwyczaj prozaiczna. Twórca tego zapytania zapomniał o podstawowej sprawie – o indeksach. Indeksy w UPDATE? Przecież indeksy przyspieszają wyszukiwanie danych, a nie ich modyfikację. Ba, indeks zmniejsza wydajność zapytań modyfikujących dane bo jeśli indeksu nie ma, to modyfikujemy tylko dane w tabeli. Jeśli natomiast indeks jest, to oprócz tabeli konieczna jest także modyfikacja danych z indeksu. Dodatkowa operacja dyskowa. O co więc chodzi z tymi indeksami w zapytaniach typu UPDATE?
czytaj dalej…

W warunku WHERE, jeśli chcemy wyciągnąć rekordy o danej zawartości kolumny, można zastosować dwie różne formy – WHERE kolumna=’coś’ i WHERE kolumna LIKE ‚coś’. Z punktu widzenia efektu, jaki twórca zapytania chce uzyskać oba sposoby dają identyczny efekt:

mysql> SELECT * FROM actor WHERE last_name='SWANK';
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        9 | JOE        | SWANK     | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM actor WHERE last_name LIKE 'SWANK';
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        9 | JOE        | SWANK     | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)

Pojawia się pytanie, czy oba sposoby są identyczne z punktu widzenia wydajności?

czytaj dalej…

W poprzednich postach pisałem o tym, jak wygląda sytuacja, gdy wypinamy wtyczkę z kontaktu – jak wygląda wymuszony restart serwera MySQL, jak wygląda odtwarzanie danych z kopii zapasowej? Niektórzy administratorzy MySQL, na wypadek zajścia takiej sytuacji, stosują różnorakie mechanizmy gwarantujące pewien poziom dostępności usług. W tym poście opiszę pokrótce dwa takie rozwiązania, omówimy także jak to się ma do wyboru silnika bazodanowego.
czytaj dalej…