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

Složený FULLTEXTOVÝ index v MySQL

Odpověď @Aldena Quimbyho je správná, pokud to jde, ale v příběhu je toho víc, protože MySQL to pouze zkusí zvolit optimální index a jeho schopnost provést toto určení je omezená kvůli způsobu interakce fulltextových indexů s optimalizátorem.

Ve skutečnosti se stane toto:

Pokud zadané user_id existuje v 0 nebo 1 odpovídajících řádcích v tabulce, optimalizátor si to uvědomí a vybere user_id jako index pro tento dotaz. Rychlé provedení.

V opačném případě zvolí optimalizátor fulltextový index a vyfiltruje každý řádek odpovídající fulltextovému indexu, aby vyloučil řádky, které neobsahují user_id odpovídající klauzuli WHERE. Ne tak rychle.

Takže to není skutečně "optimální" cesta. Je to spíše fulltext, s pěknou optimalizací, aby se zabránilo fulltextovému vyhledávání pod jednou podmínkou, že víme, že v tabulce nemáme skoro nic zajímavého.

Důvodem je, že fulltextový index nevrací optimalizátoru žádné smysluplné statistiky. Říká jen "jo, myslím, že by ten dotaz měl pravděpodobně vyžadovat pouze kontrolu 1 řádku" ... což samozřejmě optimalizátora velmi těší, takže fulltextový index vyhrává nabídku za nejnižší cenu, pokud index s celým číslem hodnota je také srovnatelně nízká nebo nižší.

To však neznamená, že bych to nejprve nezkusil tímto způsobem.

Existuje další možnost, která by nejlépe fungovala s fulltextovými dotazy IN BOOLEAN MODE a to je vytvořit další sloupec, který byste naplnili něčím jako CONCAT('user_id_',user_id) nebo něčím podobným, a poté deklarovat 2-sloupcový fulltextový index.

filter_string VARCHAR(48) # populated with CONCAT('user_id_',user_id);
....
FULLTEXT KEY (message,filter_string)

Poté vše specifikujte v dotazu.

SELECT ...
 WHERE user_id = 500 AND
 MATCH (message,filter_string) AGAINST ('+kittens +puppies +user_id_500' IN BOOLEAN MODE);

Nyní bude fulltextový index odpovědný za shodu pouze s těmi řádky, kde se koťata, štěňata a "user_id_500" objevují v kombinovaném fulltextovém indexu dvou sloupců, ale přesto byste tam chtěli mít také celočíselný filtr, abyste se ujistili, že konečné výsledky jsou omezeny navzdory jakémukoli náhodnému výskytu "user_id_500" ve zprávě.



  1. Odečtěte minuty od časové hodnoty v PostgreSQL

  2. Aktualizujte, pokud název existuje, jinak vložte - na SQL Server

  3. MariaDB JSON_KEYS() Vysvětleno

  4. java jdbc mysql konektor:jak vyřešit odpojení po dlouhé době nečinnosti