sql >> Database >  >> RDS >> Mysql

Samengestelde FULLTEXT-index in MySQL

@Alden Quimby's antwoord is correct voor zover het gaat, maar er is meer aan het verhaal, omdat MySQL alleen zal proberen om de optimale index te kiezen, en het vermogen om die bepaling te maken is beperkt vanwege de manier waarop fulltext-indexen interageren met de optimizer.

Wat er feitelijk gebeurt is dit:

Als de opgegeven user_id bestaat in 0 of 1 overeenkomende rijen in de tabel, zal de optimizer dit realiseren en user_id kiezen als de index voor die zoekopdracht. Snelle uitvoering.

Anders kiest de optimizer de volledige tekstindex, waarbij elke rij wordt gefilterd die overeenkomt met de volledige tekstindex om rijen te elimineren die geen gebruikers-ID bevatten die overeenkomt met de WHERE-component. Niet zo snel.

Het is dus niet echt het "optimale" pad. Het lijkt meer op volledige tekst, met een mooie optimalisatie om het zoeken in volledige tekst te vermijden onder de enige voorwaarde dat we weten dat we bijna niets interessants in de tabel hebben.

De reden dat dit stuk gaat, is dat een fulltext-index geen zinvolle statistieken teruggeeft aan de optimizer. Er staat alleen "ja, ik denk dat ik voor die zoekopdracht waarschijnlijk maar 1 rij hoef te controleren" ... wat de optimizer natuurlijk enorm behaagt, dus de fulltext-index wint het bod voor de laagste kosten, tenzij de index met het gehele getal waarde komt ook relatief laag of lager uit.

Dat betekent echter niet dat ik het niet eerst op deze manier zou proberen.

Er is nog een andere optie, die het beste werkt met fulltext-query's IN BOOLEAN MODE en dat is om een ​​andere kolom te maken die je zou vullen met iets als CONCAT('user_id_',user_id) of iets dergelijks, en dan een 2-koloms fulltext index declareren.

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

Specificeer vervolgens alles in de zoekopdracht.

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

Nu zal de fulltext-index verantwoordelijk zijn voor het matchen van alleen die rijen waar kittens, puppy's en "user_id_500" verschijnen in de gecombineerde fulltext-index van de twee kolommen, maar u wilt ook daar het integerfilter hebben om ervoor te zorgen dat de de uiteindelijke resultaten zijn beperkt ondanks het willekeurig verschijnen van "user_id_500" in het bericht.



  1. Roep pusher op wanneer mysql is gewijzigd

  2. Lat Lng-waarden opslaan in MySQL met behulp van Spatial Point Type

  3. Hoe te herschrijven IS ONDERSCHEIDEN VAN en IS NIET ONDERSCHEIDEN VAN?

  4. Een postgres-back-upbestand herstellen via de opdrachtregel?