Index Scan Nebo Full Scan: Co Rozhoduje O Rychlosti Dotazu

Z Mazovia

Nepodceňujte nástroje pro vývoj. Redux DevTools umožňují sledovat každou akci, skákat v čase a porovnávat strom stavu před a po. Když se aplikace chová divně, první krok je najít akci, po které se stav rozbije. Často se ukáže, že reducer mutuje původní objekt místo vytvoření nového. V produkci middleware pro logování vypněte, jinak zbytečně zpomaluje aplikaci a zaplavuje konzoli. Stejně tak kontrolujte, že žádný reducer neobsahuje náhodné hodnoty nebo volání API.

Nakonec se vyplatí měřit, ne hádat. Změňte jeden prvek, změřte dobu a plán, a teprve pak dělejte další úpravu. Sledujte nejpomalejší dotazy průběžně, protože seznam se mění s tím, jak rostou data. Výkon není jednorázový úkol, ale rutina: aktualizovat statistiky, hlídat nevyužívané indexy a kontrolovat, jestli podmínky nebrání jejich použití.

Zvažte také, co se stane, když limit překročí legitimní uživatel. Místo tvrdého zablokování můžete poslat upozornění nebo zvýšit limit po ověření. U API je dobré vracet hlavičky s informací o limitu a zbývajícím čase. To klientům umožní se přizpůsobit. Pokud potřebujete rozlišit roboty od lidí, můžete přidat jednoduchý důkaz práce, ale to už je nad rámec běžného rate limitingu. Vždy měřte, kolik požadavků končí na 429, a podle toho pravidla upravujte. Bez měření jen hádáte.

Rychlost dotazu nejčastěji nezávisí na tom, jak dlouho trvá samotný výpočet, ale na tom, kolik dat musí databáze přečíst. Pokud dotaz prochází celou tabulku, aby vrátil pár řádků, je to signál, že chybí vhodný index nebo že ho optimalizátor odmítl použít. Prvním krokem je proto zjistit skutečný plán provedení. Většina databázových systémů umí příkaz EXPLAIN nebo jeho obdobu. Sledujte, zda se u tabulky objevuje full table scan, jaký typ joinu se použil a kolik řádků se odhaduje. Právě rozdíl mezi odhadem a skutečností často ukáže, kde je problém.

Praktický postup: nejprve změřte dobu běhu dotazu a prohlédněte si plán. Potom zkuste přidat nebo upravit index a znovu změřte. Nepřidávejte indexy naslepo; každý index zpomaluje zápisy a zabírá místo. Sledujte statistiky – pokud jsou zastaralé, optimalizátor se rozhoduje podle nesprávných odhadů. Pravidelná aktualizace statistik bývá nejlevnější optimalizace, kterou můžete udělat. A nakonec: testujte na datech, která odpovídají produkci. Malá vývojová tabulka se chová úplně jinak než plná produkční.

Dalším viníkem bývá návrat příliš mnoha sloupců. Dotaz SELECT * nutí databázi načíst i data, která vůbec nepotřebujete, a zvyšuje zátěž na přenos i paměť. Vypište jen sloupce, které skutečně použijete. U spojování tabulek dávejte pozor na pořadí joinů. Menší tabulka by měla být zpracována dříve, pokud to logika dovolí. Pomáhá také omezit množství řádků co nejdříve – filtr v poddotazu nebo v CTE může výrazně zmenšit datový tok ještě před joinem.

Pokud aplikace běží ve více instancích, paměťové úložiště přestane fungovat spolehlivě. Každý proces má vlastní počítadla a limit se tak fakticky násobí. Řešením je úložiště v Redis nebo jiné sdílené databázi. express-rate-limit podporuje vlastní store; stačí předat instanci klienta. Pozor na to, že Redis musí být dostupný a nesmí se stát dalším bodem selhání. Nastavte časové limity připojení a ošetřete výpadky tak, aby aplikace nespadla, ale aby limit přešel do bezpečného režimu.

Omezení rychlosti požadavků v Node.js s Expressem není jen o tom nasadit middleware a doufat, že to bude fungovat. Špatně nastavený limit dokáže zablokovat legitimní provoz, zatímco útočník proklouzne. Základem je uvědomit si, že rate limiting není brzda pro všechny, ale ochrana konkrétních zdrojů. Nesnažte se omezovat celou aplikaci jedním globálním pravidlem. Raději si nejdřív zmapujte, které endpointy jsou citlivé – přihlašování, registrace, odesílání e-mailů, vyhledávání nebo jakákoli operace, která stojí peníze nebo výkon.

Optimalizace není jednorázový úkon. Dotazy, které byly rychlé, mohou po nárůstu dat zpomalit. Proto se vyplatí mít přehled o pomalých dotazech a čas od času zkontrolovat jejich plány. Zaměřte se na ty, které běží často, i když jsou na první pohled rychlé – jejich kumulativní dopad bývá větší než u jednoho dlouhého dotazu. Změna jedné podmínky nebo přidání jednoho vhodného indexu pak často znamená rozdíl mezi dotazem, který zatěžuje celý systém, a dotazem, který si vezme jen to, co potřebuje.

Když se index zdá být, ale dotaz ho ignoruje Častý problém: index existuje, ale optimalizátor ho nepoužije. Důvodem bývá obalení sloupce funkcí nebo výrazem. Podmínka typu WHERE YEAR(datum) = 2024 zabrání použití indexu na sloupci datum, protože databáze musí nejprve spočítat hodnotu pro každý řádek. Řešením je přepsat podmínku na rozsah: datum >= '2024-01-01' AND datum úložné prostory v malém bytě</a>ždy se snažte, aby levá strana podmínky obsahovala holý sloupec.