sql >> Databáze >  >> RDS >> Mysql

Jak optimalizovat dotazy v databázi – základy

Musíte se podívat nahoru pro každou podmínku a pro každé připojení...za podmínky. Oba fungují stejně.

Předpokládejme, že píšeme

select name
from customer
where customerid=37;

Nějakým způsobem musí DBMS najít záznam nebo záznamy s customerid=37. Pokud neexistuje žádný index, jediným způsobem, jak to udělat, je přečíst každý záznam v tabulce porovnávající id zákazníka s číslem 37. I když nějaký najde, nemůže zjistit, že existuje pouze jeden, takže musí hledat dál ostatní.

Pokud vytvoříte index na customerid, DBMS má způsoby, jak index velmi rychle prohledávat. Nejde o sekvenční vyhledávání, ale v závislosti na databázi o binární vyhledávání nebo jinou účinnou metodu. Nezáleží na tom, jak přesně, uznejte, že je to mnohem rychlejší než sekvenční. Index jej pak přenese přímo do příslušného záznamu nebo záznamů. Kromě toho, pokud určíte, že index je „unikátní“, pak databáze ví, že může být pouze jeden, takže neztrácí čas hledáním druhého. (A DBMS vám zabrání přidat sekundu.)

Nyní zvažte tento dotaz:

select name
from customer
where city='Albany' and state='NY';

Nyní máme dvě podmínky. Pokud máte index pouze v jednom z těchto polí, DBMS použije tento index k nalezení podmnožiny záznamů a následně je prohledá. Například, pokud máte index na stavu, DBMS rychle najde první záznam pro NY, poté bude postupně hledat město='Albany' a přestane hledat, když dosáhne posledního záznamu pro NY.

Pokud máte index, který obsahuje obě pole, tj. „vytvořit index o zákazníkovi (stát, město)“, může DBMS okamžitě přiblížit na správné záznamy.

Máte-li dva samostatné indexy, jeden pro každé pole, bude mít DBMS různá pravidla, která použije při rozhodování, který index použít. Opět, přesně jak se to dělá, závisí na konkrétním DBMS, který používáte, ale v zásadě se snaží vést statistiky o celkovém počtu záznamů, počtu různých hodnot a rozložení hodnot. Poté bude v těchto záznamech postupně vyhledávat ty, které splňují druhou podmínku. V tomto případě by DBMS pravděpodobně zjistil, že existuje mnohem více měst než států, takže pomocí indexu měst může rychle přiblížit záznamy 'Albany'. Poté je postupně prohledá a zkontroluje stav každého proti 'NY'. Pokud máte záznamy pro Albany v Kalifornii, budou přeskočeny.

Každé připojení vyžaduje určitý druh vyhledávání.

Řekněme, že píšeme

select customer.name
from transaction
join customer on transaction.customerid=customer.customerid
where transaction.transactiondate='2010-07-04' and customer.type='Q';

Nyní se musí DBMS rozhodnout, kterou tabulku číst jako první, vybrat z ní příslušné záznamy a poté najít odpovídající záznamy v druhé tabulce.

Pokud byste měli index na adrese Transaction.transactiondate a customer.customerid, nejlepším plánem by pravděpodobně bylo najít všechny transakce s tímto datem a poté pro každou z nich najít zákazníka s odpovídajícím customerid a poté ověřit, že zákazník má správný typ.

Pokud nemáte index na customer.customerid, pak by DBMS mohl transakci rychle najít, ale pro každou transakci by musel postupně prohledávat tabulku zákazníků a hledat odpovídající customerid. (To by bylo pravděpodobně velmi pomalé.)

Předpokládejme místo toho, že jediné indexy, které máte, jsou transakce.customerid a customer.type. Pak by DBMS pravděpodobně použil úplně jiný plán. Pravděpodobně by to naskenovalo tabulku zákazníků pro všechny zákazníky se správným typem, pak by pro každého z nich našlo všechny transakce pro tohoto zákazníka a postupně je prohledalo pro správné datum.

Nejdůležitějším klíčem k optimalizaci je zjistit, jaké indexy skutečně pomohou, a tyto indexy vytvořit. Další, nepoužívané indexy zatěžují databázi, protože jejich údržba vyžaduje práci, a pokud nejsou nikdy použity, je to zbytečné úsilí.

Pomocí příkazu EXPLAIN můžete zjistit, jaké indexy bude DBMS používat pro daný dotaz. Toto používám neustále, abych zjistil, zda jsou mé dotazy dobře optimalizovány, nebo zda bych měl vytvářet další indexy. (Přečtěte si dokumentaci k tomuto příkazu pro vysvětlení jeho výstupu.)

Upozornění:Pamatujte, že jsem řekl, že DBMS vede v každé tabulce statistiky o počtu záznamů a počtu různých hodnot a tak dále. EXPLAIN vám dnes může poskytnout úplně jiný plán než včera, pokud se data změnila. Máte-li například dotaz, který spojuje dvě tabulky a jedna z těchto tabulek je velmi malá, zatímco druhá je velká, bude upřednostněn tak, aby nejprve přečetl malou tabulku a poté našel odpovídající záznamy ve velké tabulce. Přidávání záznamů do tabulky může změnit, která je větší, a tím vést DBMS ke změně plánu. Proto byste se měli pokusit provést EXPLAINS proti databázi s realistickými daty. Běh proti testovací databázi s 5 záznamy v každé tabulce má mnohem menší hodnotu než běh proti živé databázi.

No, dalo by se říct mnohem víc, ale nechci tu psát knihu.



  1. Jak mohu použít jarní data jpa k dotazu na sloupec jsonb?

  2. Jak seskupit podle user_id a objednat podle desc

  3. Upozornění:Nepodařilo se otevřít stream:Žádný takový soubor nebo adresář v C:\wamp\www\laravel\bootstrap\autoload.php na řádku 17

  4. SQL select where not in subdotaz nevrací žádné výsledky