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

Złożony indeks FULLTEXT w MySQL

Odpowiedź @Alden Quimby jest poprawna, jeśli chodzi o to, że jest poprawna, ale jest coś więcej, ponieważ MySQL będzie tylko spróbował wybrać optymalny indeks, a jego zdolność do dokonania tego ustalenia jest ograniczona ze względu na sposób, w jaki indeksy pełnotekstowe współdziałają z optymalizatorem.

W rzeczywistości dzieje się tak:

Jeśli określony identyfikator_użytkownika istnieje w 0 lub 1 pasujących wierszach w tabeli, optymalizator zda sobie z tego sprawę i wybierze identyfikator_użytkownika jako indeks dla tego zapytania. Szybka realizacja.

W przeciwnym razie optymalizator wybierze indeks pełnotekstowy, filtrując każdy wiersz dopasowany przez indeks pełnotekstowy w celu wyeliminowania wierszy nie zawierających identyfikatora użytkownika, który pasuje do klauzuli WHERE. Nie tak szybko.

Więc to nie jest naprawdę „optymalna” ścieżka. To bardziej przypomina pełny tekst, z ładną optymalizacją, aby uniknąć wyszukiwania pełnotekstowego pod jednym warunkiem, że wiemy, że nie mamy prawie nic interesującego w tabeli.

Powodem tego jest to, że indeks pełnotekstowy nie zwraca żadnych znaczących statystyk do optymalizatora. Po prostu mówi "tak, myślę, że to zapytanie powinno prawdopodobnie wymagać ode mnie tylko sprawdzenia 1 wiersza" ... co oczywiście bardzo podoba się optymalizatorowi, więc indeks pełnotekstowy wygrywa ofertę za najniższy koszt, chyba że indeks z liczbą całkowitą wartość jest również porównywalnie niska lub niższa.

Nie oznacza to jednak, że nie próbowałbym tego najpierw w ten sposób.

Istnieje inna opcja, która najlepiej sprawdziłaby się w przypadku zapytań pełnotekstowych IN BOOLEAN MODE to jest utworzenie kolejnej kolumny, którą można wypełnić wartością typu CONCAT('user_id_',user_id) lub czymś podobnym, a następnie zadeklarować 2-kolumnowy indeks pełnotekstowy.

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

Następnie określ wszystko w zapytaniu.

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

Teraz indeks pełnotekstowy będzie odpowiedzialny za dopasowanie tylko tych wierszy, w których kocięta, szczenięta i „user_id_500” pojawiają się w połączonym indeksie pełnotekstowym dwóch kolumn, ale nadal warto mieć tam również filtr liczb całkowitych, aby upewnić się, że wyniki końcowe są ograniczone pomimo przypadkowego pojawienia się „user_id_500” w wiadomości.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MYSQL otrzymuje wszystkie wyniki, ale najpierw

  2. MySQL - CONCAT - Czy istnieje sposób na połączenie ciągu i użycie go jako zmiennej?

  3. Wyłącz ostrzeżenia i błędy w PHP i MySQL

  4. Funkcja MySQL RAND() – Generuj liczbę losową w MySQL

  5. MySQL - Jak wybrać dane według długości łańcucha