Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Indeksy pełnotekstowe i złożone oraz ich wpływ na zapytanie

Jeśli rozumiem twoje pytanie, wiesz, że funkcja MATCH AGAINST używa twojego indeksu FULLTEXT i zastanawiasz się, w jaki sposób MySQL stosuje resztę klauzuli WHERE (tj. czy wykonuje skanowanie tabel lub wyszukiwanie indeksowane).

Oto, co zakładam w odniesieniu do Twojej tabeli:ma ona KLUCZ PODSTAWOWY w jakiejś kolumnie identyfikatora i indeks FULLTEXT.

Więc po pierwsze, MySQL nigdy użyj indeksu FULLTEXT dla klauzuli WHERE miasta/stanu. Czemu? Ponieważ indeksy PEŁNOTEKSTOWE mają zastosowanie tylko z opcją DOPASUJ PRZECIW. Zobacz tutaj w akapicie po pierwszym zestawie punktorów (nie punktorach Spisu treści).

EDYTUJ: W twoim przypadku, zakładając, że twoja tabela ma nie tylko 10 wierszy, MySQL zastosuje indeks FULLTEXT dla twojego MATCH AGAINST, a następnie przeskanuje tabele tych wyników, aby zastosować miasto/stan GDZIE.

A co, jeśli dodasz indeks BTREE do miasta i stanu?

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

Cóż, MySQL może używać tylko jednego indeks dla tego zapytania, ponieważ jest to prosty wybór. Będzie albo użyj PEŁNEGO TEKSTU lub BTREE. Zauważ, że kiedy mówię o jednym indeksie, mam na myśli jedną definicję indeksu, a nie jedną kolumnę w indeksie wieloczęściowym. Tak czy inaczej, to nasuwa się pytanie, co robi go używać?

To zależy od analizy tabeli. MySQL spróbuje oszacować (na podstawie statystyk tabeli z ostatniej OPTIMIZE TABLE), który indeks usunie najwięcej rekordów. Jeśli miasto/stan GDZIE sprowadza się do 10 rekordów, podczas gdy MATCH AGAINST tylko do 100, MySQL użyje indeksu city__state najpierw dla miasta/stanu GDZIE, a następnie przeskanuj tabele dla opcji MECZ PRZECIW.

Z drugiej strony, jeśli MATCH_AGAINST sprowadzi Cię do 10 rekordów, podczas gdy miasto/stan GDZIE sprowadzi Cię tylko do 1000, wtedy MySQL zastosuje najpierw indeks FULLTEXT i przeskanuje tabele dla miasta i stanu.

Najważniejsze jest liczność swojego indeksu. Zasadniczo, jak unikalne są wartości, które trafią do Twojego indeksu? Jeśli każdy rekord w tabeli ma miasto ustawione na Oakland, to nie jest to bardzo unikalny klucz, a zatem city =„Oakland” nie zmniejsza tak bardzo liczby rekordów. W takim przypadku mówimy, że indeks city__state ma niską kardynalność .

W związku z tym, jeśli 90% słów w indeksie PEŁNOTEKSTOWYM to „Jan”, to tak naprawdę nie pomoże Ci to z dokładnie tych samych powodów.

Jeśli możesz sobie pozwolić na miejsce i narzut UPDATE/DELETE/INSERT, sugerowałbym dodanie indeksu BTREE i pozwolenie MySQLowi na podjęcie decyzji, którego indeksu chce użyć. Z mojego doświadczenia wynika, że ​​zwykle bardzo dobrze wybiera właściwy.

Mam nadzieję, że to odpowiedź na twoje pytanie.

EDYTUJ: Na marginesie, upewnij się, że wybrałeś odpowiedni rozmiar dla swojego indeksu BTREE (w moim przykładzie wybrałem pierwsze 10 znaków w mieście). To oczywiście ma ogromny wpływ na kardynalność. Jeśli wybrałeś miasto (1), to oczywiście otrzymasz niższą kardynalność niż w przypadku wybrania miasta (10).

EDIT2: Plan zapytań MySQL (oszacowanie), dla którego indeks usuwa najwięcej rekordów, jest tym, co widzisz w EXPLAIN.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hierarchiczne menu rekurencji z PHP/MySQL

  2. Błąd łącznika MySQL Wartość strefy czasowej serwera Czas środkowoeuropejski

  3. Problem z porównywaniem dat MySQL

  4. Mysql nie uruchamia się po aktualizacji Mac OS X Yosemite (Mac OS 10.10)

  5. To zapytanie SELECT zajmuje 180 sekund, aby zakończyć