Przejdź do treści

MySQL – optymalizacja i wydajność

O pracy MySQL DBA – przemyślenia administratora

Archiwa

Archiwa z daty Listopad, 2010

Co do zasady, MySQL nie umie wykorzystać więcej niż jeden indeks do danego zapytania. Jeśli możliwe jest skorzystanie z indeksu, optimizer stara się wybrać najbardziej optymalny z dostępnych indeksów. Może to być indeks obejmujący kilka kolumn, ale jest to jeden indeks. Od tej zasady jest jednak jeden wyjątek – Index Merge. Jest to algorytm, który umożliwia połączenie wyników kilku skanów różnych indeksów w jeden. Tak aby być precyzyjnym, są to trzy różne algorytmy:
czytaj dalej…

Tym razem trochę prywaty. Jak być może stali czytelnicy zauważyli, na stronie, obok linka do formularza kontaktowego pojawił się nowy link.

Często jest tak, że serwis po prostu działa. Ktoś go kiedyś zainstalował na serwerze, skonfigurował jako tako i od tego czasu funkcjonuje sobie w miarę rześko. Niestety, czasami pojawia się problem – a to ruch jest za duży, a to zmienia się wersja serwera bazodanowego i trzeba przeprowadzić migrację. Czasami po prostu potrzeba przygotować jakieś nowe rozwiązanie, zapewniające stabilność działania usług, bo internetowy biznes tak się  ładnie rozkręcił, że każda minuta przestoju serwisu to już wymierne straty. Dlaczego w takich sytuacjach warto zatrudnić osobę z zewnątrz?

Na pierwszy rzut oka jest to droższe niż rozwiązanie problemu własnymi siłami. W końcu, większość rozwiązań stosowanych wraz z MySQL to rozwiązania Open Source. Zazwyczaj jakąś tam dokumentację udostępniają, how-to na Google też można znaleźć. Pytanie tylko, czy czas poświęcony na naukę nowego rozwiązania nie będzie ostatecznie więcej warty niż pieniądze wydane na zatrudnienie konsultanta? Szczególnie dobrze jest to policzyć, jeśli daną operację planuje się wykonywać raz na kilka lat (jak np. zmiana wersji MySQL czy gruntowna przebudowa architektury serwisu). Dodatkowo, jeśli zdecydujemy sami się zmierzyć z problemem, jesteśmy zdani tylko na siebie i uczymy się na własnych błędach. Konsultant takich problemów rozwiązywał już w swojej dotychczasowej historii pracy znacznie więcej, ma więc znacznie większe doświadczenie i wie gdzie są ukryte jakieś haczyki.

Na dziś tyle kryptoreklamy. Jutro nowy wpis, który dotyczyć będzie algorytmu ‚index merge’.

Dzisiejszy post to odpowiedź na jedno z zapytań z Google. Czy da się skonfigurować replikację tak, aby masterem był serwer MySQL w wersji 5.1 a slave MySQL w wersji 5.0? Zgodnie z dokumentacją, replikacja z nowszej wersji do starszej nie jest wspierana, ale w niektórych przypadkach da się to zrobić. Przyznam, że osobiście tego typu potrzeby nie miałem, ciężko z resztą autorytatywnie stwierdzić, że tego typu konfiguracja jest możliwa, bądź nie. Zbyt dużo tu zależy od konkretnych zapytań, które mają się replikować. Co wiemy na pewno?
czytaj dalej…

MySQL udostępnia bezpośredni dostęp do silników InnoDB i MyISAM – realizowany jest on przy pomocy polecenia HANDLER. Jego zasada działania sprowadza się z grubsza do tego, że operuje on na indeksie i pobiera rekord dla danego wpisu w indeksie. Wygląda to mniej więcej tak:

HANDLER tabela OPEN;
HANDLER tabela READ jakis_indeks='jakas wartosc';

Efektem powyższego jest zwrócenie zawartości rekordu, w przypadku którego kolumna indeksowana przez indeks „jakis_indeks” posiada wartość „jakas wartosc”. Więcej szczegółów na ten temat można oczywiście znaleźć w dokumentacji MySQL. Zgodnie z dokumentacją, HANDLER jest szybszy niż SELECT. Wiąże się to z tym, że odpada problem z koniecznością analizy i parsowania SQL, nie jest konieczny udział optimizera (bo skoro nie ma SQL, to nie bardzo co jest optymizować), nie stosuje się lockowanie tabel, tak więc odpada kolejny element do pilnowania. Sprawdźmy z resztą dokładnie jak to wygląda w praktyce:
czytaj dalej…

Nie będę się rozpisywać na temat tego, czym są klucze obce. Jeśli ktoś nie miał okazji się z nimi zetknąć, zapraszam do Google. Chciałbym natomiast napisać o tym, jakie wymogi muszą być spełnione, aby klucz obcy mógł zostać utworzony. Nie do końca jest to jasne, a świadczy o tym choćby fakt pojawienia się na jednym z czytanych przeze mnie forów opisu problemu z tworzeniem takiego klucza.

Załóżmy, że mamy dwie tabele, które tworzymy w następujący sposób:

CREATE TABLE tab1 (tab1_id SERIAL, tab2_id INT, CONSTRAINT pk PRIMARY KEY (tab1_id)) ENGINE=InnoDB;
CREATE TABLE tab2 (tab2_id SERIAL, kol INT, CONSTRAINT pk2 PRIMARY KEY (tab2_id)) ENGINE=InnoDB;

Chcemy je połączyć kluczem obcym na kolumnach tab2_id. Próbujemy taki klucz obcy utworzyć:

mysql> ALTER TABLE tab1 ADD CONSTRAINT tab1_tab2_fk FOREIGN KEY (tab2_id) REFERENCES tab2(tab2_id);
ERROR 1005 (HY000): Nie można stworzyć tabeli 'test.#sql-6ed0_b0a9' (Kod błędu: 150)

Co jest nie tak?

czytaj dalej…

Być może do części czytelników dotarł już poniższy link:

http://www.mysql.com/products/

MySQL w wersji z InnoDB za $2000? Ciekawe.  Na Twitterze szerzy się panika, użytkownicy Postgresql zacierają ręce…

Na szczęście, nie jest tak źle, jakby to wyglądało na pierwszy rzut oka. W przypadku MySQL Community Edition, czyli wersji opartej na licencji GPL, InnoDB jest, ma się dobrze i pozostanie dostępne. Przynajmniej tak twierdzi Oracle. Jeśli tak będzie, to nic się tragicznego nie stało – w końcu MySQL używane na komercyjnej licencji, z supportem i całą resztą dobrobytu,  nie jest zbyt często spotykane – szczególnie w Polsce.

Pożyjemy, zobaczymy. W każdym razie, Oracle wpadło na bardzo specyficzny pomysł…

Jeden z czytelników w komentarzu zapytał się, czy wykonywałem testy jak włączenie dodatkowych statystyk wpływa na działanie serwera. Fakt jest taki, że takich testów nie wykonywałem. Tego typu dane są mi niezbędnie potrzebne do skutecznego administrowania serwerami MySQL w środowisku, w jakim pracuję. Zadowoliłem się stwierdzeniem, że ich wpływ jest niewielki. Skoro jednak temat się pojawił, to takie testy wykonałem. Sprowadziło się to do wykonania w pętli 60 razy polecenia:

sysbench  --test=oltp --mysql-user=root --oltp-table-size=10000000  --num-threads=128 --max-requests=10000 --mysql-table-engine=innodb  --mysql-db=sbtest --oltp-read-only=off --oltp-test-mode=complex run

W przypadku wyłączonych statystyk (set global userstat_running=0;) średnia to 917,4 transakcji na sekundę.

Po włączeniu statystyk (set global userstat_running=1;) średnia spadła do 878,7 transakcji na sekundę.

Jak widać, spadek wydajności to ok. 5% Dla mnie jest to wartość jak najbardziej do zaakceptowania, biorąc pod uwagę ilość informacji, jakie uzyskuję dzięki tym statystykom.