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

MySQL EXPLAIN 'type' se změní z 'range' na 'ref', když se změní datum v příkazu where?

Různé vyhledávací strategie dávají smysl pro různá data. Zejména skenování indexu (jako je rozsah) často musí provést hledání, aby skutečně přečetlo řádek. V určitém okamžiku je provádění všech těchto hledání pomalejší než nepoužívání indexu vůbec.

Vezměte si triviální příklad, tabulku se třemi sloupci:id (primární klíč), jméno (indexováno), narozeniny. Řekněme, že má hodně dat. Pokud požádáte MySQL, aby vyhledával Bobovy narozeniny, může to udělat poměrně rychle:nejprve najde Boba v indexu jmen (to trvá několik hledání, log(n), kde n je počet řádků), pak jedno další hledání přečíst aktuální řádek v datovém souboru a přečíst z něj narozeniny. To je velmi rychlé a mnohem rychlejší než skenování celé tabulky.

Dále zvažte vytvoření name like 'Z%' . To je pravděpodobně poměrně malá část tabulky. Takže je stále rychlejší najít, kde začínají Zs v indexu názvů, pak pro každý vyhledat datový soubor, aby se řádek přečetl. (Toto je skenování rozsahu).

Nakonec zvažte dotaz na všechna jména začínající na M-Z. To je pravděpodobně polovina údajů. Mohlo by to provést skenování rozsahu a pak hodně hledání, ale náhodné prohledávání datového souboru s konečným cílem přečíst polovinu řádků není optimální:bylo by rychlejší jednoduše provést velké sekvenční čtení datového souboru. Takže v tomto případě bude index ignorován.

To je to, co vidíte – kromě vašeho případu existuje ještě jeden klíč, na který se může vrátit. (Je také možné, že by mohl skutečně použít index data, pokud by neměl ten druhý, měl by vybrat index, který bude nejrychlejší. Pozor, optimalizátor MySQL v tomto často dělá chyby.)

Takže se to zkrátka očekává. Dotaz neříká jak k načtení dat, spíše říká co data k načtení. Optimalizátor databáze by měl najít nejrychlejší způsob, jak ji získat.

Můžete najít rejstřík na obě sloupců v pořadí (public_key,created_on_date) je preferován v obou případech a urychluje váš dotaz. Je to proto, že MySQL může vždy používat pouze jeden index na tabulku (na dotaz). Datum je také na konci, protože skenování rozsahu lze efektivně provést pouze v posledním sloupci v indexu.

[Věřím, že InnoDB má ve skutečnosti další vrstvu nepřímosti, ale jen by to zmátlo pointu. Na vysvětlení to nic nemění.]




  1. Migrace z Postgres na SQL Server 2008

  2. Pochopení transakcí v SQL

  3. Jak mohu obnovit plná oprávnění uživatele root MySQL?

  4. Hodnoty výchozího bodu MySQL RAND() se téměř opakují