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

Fulltextové a složené indexy a jak ovlivňují dotaz

Pokud rozumím vaší otázce, víte, že MATCH AGAINST používá váš FULLTEXTOVÝ index a zajímá vás, jak MySQL postupuje při aplikaci zbytku klauzule WHERE (tj. zda provádí prohledávání tabulek nebo indexované vyhledávání).

O vaší tabulce předpokládám toto:má PRIMÁRNÍ KLÍČ v některém sloupci id a FULLTEXTOVÝ index.

Takže za prvé, MySQL nebude nikdy použijte FULLTEXT index pro klauzuli města/státu WHERE. Proč? Protože FULLTEXT indexy platí pouze s MATCH AGAINST. Viz zde v odstavci za první sadou odrážek (nikoli odrážky obsahu).

UPRAVIT: Ve vašem případě, za předpokladu, že vaše tabulka nemá pouze 10 řádků, MySQL použije FULLTEXTOVÝ index pro váš ZÁPAD PROTI, poté provede prohledání tabulek těchto výsledků, abyste použili město/stát KDE.

Co když tedy do města a státu přidáte index BTREE?

CREATE INDEX city__state ON table (city(10),state(2)) USING BTREE;

MySQL může používat pouze jeden index pro tento dotaz, protože jde o jednoduchý výběr. Bude buď použijte FULLTEXT nebo BTREE. Všimněte si, že když říkám jeden index, myslím tím jednu definici indexu, nikoli jeden sloupec ve vícedílném indexu. Anwway, to pak vyvolává otázku, který z nich dělá používá?

To záleží na analýze tabulky. MySQL se pokusí odhadnout (na základě statistik tabulky z poslední OPTIMIZE TABLE), který index odstraní nejvíce záznamů. Pokud vás město/stát WHERE dostane na 10 záznamů, zatímco MATCH AGAINST vás dostane pouze na 100, pak MySQL použije index city__state nejprve pro město/stát WHERE a poté proveďte prohledání MATCH PROTI.

Na druhou stranu, pokud vás MATCH_AGAINST dostane na 10 záznamů, zatímco město/stát WHERE vás dostane na pouhých 1000, pak MySQL použije nejprve FULLTEXT index a prohledá město a stát pomocí tabulek.

Základem je kardinalita vašeho indexu. Jak jedinečné jsou v zásadě hodnoty, které půjdou do vašeho indexu? Pokud má každý záznam ve vaší tabulce město nastaveno na Oakland, pak to není příliš jedinečný klíč, a proto má city ='Oakland' ve skutečnosti pro vás tolik nesnižuje počet záznamů. V takovém případě říkáme, že váš index city__state má nízkou mohutnost .

Pokud je tedy 90 % slov ve vašem FULLTEXTOVÉM indexu „John“, pak vám ani to moc nepomůže, a to ze stejných důvodů.

Pokud si můžete dovolit prostor a režii UPDATE/DELETE/INSERT, doporučil bych přidat index BTREE a nechat MySQL rozhodnout, který index chce použít. Podle mých zkušeností obvykle odvádí velmi dobrou práci při výběru toho správného.

Doufám, že to odpovídá na vaši otázku.

UPRAVIT: Na okraj, ujistěte se, že jste vybrali správnou velikost pro váš index BTREE (v mém příkladu jsem vybral prvních 10 znaků ve městě). To má zjevně obrovský dopad na mohutnost. Pokud jste vybrali město (1), pak samozřejmě dostanete nižší mohutnost, než kdybyste vybrali město (10).

EDIT2: Plán dotazů MySQL (odhad), pro který index ořezává nejvíce záznamů, je to, co vidíte v EXPLAIN.



  1. Export databáze pomocí MySQL Workbench s příkazy INSERT

  2. Jak vytvořit CreatedOn a UpdatedOn pomocí EF Core 2.1 a Pomelo

  3. Zvyšte pole databáze mysql pomocí syntaxe aktivního záznamu codeigniter

  4. Protokol transakcí serveru SQL – část 2