Odborníci vědí, jak psát výkonově efektivní dotazy. I když zkušenost dozrává moudrost, jsou určité věci, kterým člověk musí rozumět alespoň pro začátek. Musíte například porozumět klíčovým aspektům návrhu dotazu; jak interně funguje dotaz, kde selže, vzory optimalizace atd. V tomto článku poskytnu několik optimalizačních bodů, o kterých je třeba přemýšlet při navrhování dotazu v MySQL.
Proč jsou některé dotazy pomalé?
Běžným problémem s SQL dotazy je, že se načítá více dat, než je skutečně potřeba. Samozřejmě existují dotazy, které prosívají spoustu dat a my s nimi moc nenaděláme, ale nejsou běžné. Ve většině případů je to špatný návrh dotazu, který vede ke špatnému výkonu dotazu. Po každém návrhu dotazu se musíte podívat na několik aspektů, jako je to, co se může stát po spuštění dotazu:
- Zpřístupní dotaz SQL příliš mnoho sloupců nebo řádků?
- Bude server MySQL analyzovat příliš mnoho řádků, aby získal požadovaný výsledek?
Existují dotazy, které způsobují, že server MySQL analyzuje příliš mnoho dat, ale vyhodí je, když je prosévá. To je pro server práce navíc z hlediska mnoha aspektů, jako je režie sítě, příliš velká spotřeba paměti nebo příliš velké využití prostředků CPU na serveru. Důsledkem je pomalý výkon.
Jsou situace, kdy si s jeho návrhem možná moc nepomůžete, ale jsou situace, kdy když budete opatrní a odhadnete důsledek a zahledíte se do sebe, tak špatný dotaz může být alespoň dobrý, ne-li lepší.
Typické chyby a jejich řešení
Při psaní dotazu se často dělá několik běžných chyb. Zde je několik z nich. Na stejném řádku najdete několik dalších úvah. Zde jsou důvody pomalého výkonu dotazů s možnými řešeními.
Příliš mnoho řádků
Chyba se často dělá při psaní dotazu, který načítá data, a předpokládá se, že MySQL poskytne výsledek na vyžádání, přičemž se přehlédne množství zpracování potřebné k vrácení úplné sady výsledků. Předpokládejme, že se spustí příkaz SELECT k načtení 100 podrobností o produktech pro web elektronického obchodu, když je potřeba nejprve zobrazit pouze 10 z nich. Možná si myslíte, že MySQL načte pouze 10 řádků a zastaví provádění dotazu. Ale ne. MySQL dělá generování kompletní sady výsledků a dodává klientovi. Klientská knihovna obdrží kompletní sadu a většinu z ní zahodí a ponechá si pouze 10 z nich, které hledá. To zjevně plýtvá spoustou zdrojů.
V takové situaci však můžete poskytnout řešení pomocí klauzule LIMIT s dotazem.
SELECT col1, col2,... FROM table_name LIMIT [offset,] count;
Klauzule LIMIT přijímá jeden nebo dva parametry. První určuje offset a druhý určuje počet. Pokud je zadán pouze jeden parametr, udává počet řádků od začátku sady výsledků.
Chcete-li například vybrat 10 řádků z tabulky, můžete napsat:
SELECT e.emp_name, e.phone, e.email FROM employee e LIMIT 10;
A pro výběr dalších 10 řádků, počínaje 11 záznamem, můžete napsat:
SELECT e.emp_name, e.phone, e.email FROM employee e LIMIT 10, 10;
Příliš mnoho sloupců
Vždy se na dotaz:SELECT * dívejte s podezřením. Tento dotaz vrátí všechny sloupce a pravděpodobně potřebujete pouze některé z nich. Největší nevýhodou načítání všech sloupců je, že brání optimalizaci tím, že brání použití indexů, vyžaduje příliš mnoho I/O, paměti a CPU zdrojů ze serveru.
Pochopte, že takový univerzální dotaz načítající všechny sloupce může být plýtvání. Někteří říkají, že jsou užitečné, protože umožňují vývojářům používat stejný bit kódu na více než jednom místě. To je v pořádku, pokud jsou náklady s tím spojené. V tomto kontextu pomáhá někdy ukládání načtených dat do mezipaměti. Buďte však opatrní, využití výkonu je elegantní práce a takový luxus nemusí mít místo pro výkon.
Základním pravidlem je vyhnout se takovým univerzálním dotazům nebo omezit počet načtených sloupců na co nejmenší.
Příliš mnoho analýzy dat
Dotazy vracejí požadovaný výsledek, což je v pořádku, ale někdy jsou tyto dotazy zapsány tak, že při zpracování vyžaduje před generováním výsledků prozkoumání příliš velkého množství dat. Proto v MySQL musíte měřit podle následujících nákladových metrik:
- Doba provedení
- Zkontrolované řádky
- Zkontrolované sloupce
Z těchto metrik můžete získat hrubý odhad nákladů na dotaz. Ty odrážejí množství interního přístupu k datům MySQL pro zpracování dotazu a rychlost běhu dotazu. Vzhledem k tomu, že tyto metriky jsou protokolovány v protokolu pomalých dotazů, je vhodné prozkoumat a najít dotazy, které analyzují příliš mnoho dat, než aby vrátily výsledek. Databáze MySQL registruje všechny dotazy, které překročí danou dobu provádění, v protokolu pomalých dotazů. Toto je ideální místo, kde hledat pomalé dotazy a zjistit, jak často jsou pomalé.
Protokol pomalého dotazu se obvykle nachází na adrese /var/log/mysql/mysql-slow.log
Všimněte si, že možná budete muset nastavit a povolit protokolování pomalých dotazů v mysqld.cnf konfiguračním souborem následovně.
#slow_query_log = 1 #slow_query_log_file = /var/log/mysql/mysql-slow.log #long_query_time = 2
Před a s MySQL 5 existovala vážná omezení, zejména chybějící podpora pro jemnozrnné protokolování. Jediným oddechem bylo použití oprav, které umožňovaly protokolování. Tato funkce však byla součástí serverů MySQL 5.1 a novějších jako součást její základní funkce.
Dotazy, jejichž provádění trvá příliš dlouho, nemusí nutně znamenat, že se jedná o špatné dotazy. Protokol pomalých dotazů jednoduše poskytuje příležitost prověřit výkon dotazu a co nejvíce jej zlepšit.
Dotazy na restrukturalizaci
Vzhledem k tomu, že máte možnost restrukturalizovat problematické dotazy, vaším primárním cílem by mělo být najít alternativní řešení k dosažení požadovaného efektu. Dotaz můžete transformovat do jeho ekvivalentní podoby s ohledem na vnitřní efekt na serveru MySQL při zpracování.
Jedním rozhodnutím při návrhu dotazu je, zda bychom měli upřednostnit jeden složitý dotaz namísto několika jednoduchých nebo naopak. Konvenčním přístupem návrhu databáze je dělat co nejvíce prací s menším počtem dotazů. Důvodem je, že jeden velký/složitý dotaz je cenově výhodnější z hlediska navázání databázového spojení. Výhodou snížení nákladů ve prospěch komplexního dotazování je využití sítě, zpracování/optimalizace dotazů a využití zdrojů. Ale tento tradiční přístup se s MySQL nehodí. MySQL je navržen tak, aby rychle zvládl připojení a odpojení databáze. Proto se navázání spojení, spouštění mnoha jednodušších dotazů a uzavření spojení zdá efektivnější. Načítání dat prostřednictvím více než jednoho jednoduchého dotazu namísto jednoho velkého složitého je efektivnější. Všimněte si, že stejný nápad nelze použít s jinými databázemi.
Závěr
Toto je několik rychlých tipů pro optimalizaci dotazů. Pochopte, že znalost syntaxe SQL nestačí vytvořit dotaz, který získá požadovaný výsledek, pokud se člověk zaměřuje na výkon dotazu. Pochopení toho, co se děje pod zdánlivě jednoduše vypadajícími dotazy, je životně důležité při psaní dotazu, který nejenže získá to, co je požadováno, ale naplní umění optimalizace přímo tam, kde to všechno začíná. Zákulisní dění při zpracování dotazů poskytuje důležité vodítko k pochopení výkonu dotazů a tyto znalosti jsou nezbytností před jedním vpádem do oblasti optimalizace dotazů.