sql >> Databasteknik >  >> RDS >> Mysql

Fulltext och sammansatta index och hur de påverkar frågan

Om jag förstår din fråga vet du att MATCH MOT använder ditt FULLTEXT-index och du undrar hur MySQL går tillväga för att tillämpa resten av WHERE-satsen (dvs. gör den en tabellskanning eller en indexerad uppslagning).

Det här är vad jag antar om din tabell:den har en PRIMÄRNYCKEL på någon id-kolumn och FULLTEXT-indexet.

Så först och främst kommer MySQL aldrig använd FULLTEXT-indexet för stad/stat WHERE-satsen. Varför? Eftersom FULLTEXT-index endast gäller med MATCH MOT. Se här i stycket efter den första uppsättningen punkter (inte innehållsförteckningen punkter).

EDIT: I ditt fall, förutsatt att din tabell inte bara har ungefär 10 rader, kommer MySQL att tillämpa FULLTEXT-indexet för din MATCH MOT, sedan gör en tabellskanning av dessa resultat för att tillämpa staden/staten WHERE.

Så vad händer om du lägger till ett BTREE-index på stad och stat?

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

Jo MySQL kan bara använda en index för den här frågan eftersom det är ett enkelt val. Det kommer antingen använd FULLTEXT eller BTRÄDET. Observera att när jag säger ett index menar jag en indexdefinition, inte en kolumn i ett flerdelat index. Anwway, detta väcker då frågan vilken man gör använder den?

Det beror på tabellanalysen. MySQL kommer att försöka uppskatta (baserat på tabellstatistik från den senaste OPTIMERA TABELL) vilket index kommer att beskära flest poster. Om staden/staten WHERE får dig ner till 10 poster medan MATCH MOT bara får dig ner till 100, kommer MySQL att använda city__state-indexet först för staden/staten WHERE och gör sedan en tabellsökning för MATCH MOT.

Å andra sidan, om MATCH_AGAINST får dig ner till 10 poster medan staden/staten WHERE får dig ner till endast 1000, kommer MySQL att tillämpa FULLTEXT-indexet först och tabellsöka efter stad och stat.

Summan av kardemumman är kardinalitet av ditt index. I grund och botten, hur unika är värdena som kommer in i ditt index? Om varje post i din tabell har stad satt till Oakland, så är det inte en särskilt unik nyckel och därför har city ='Oakland' minskar inte antalet poster så mycket för dig. I så fall säger vi att ditt stad__statsindex har en låg kardinalitet .

Följaktligen, om 90 % av orden i ditt FULLTEXT-index är "John", så hjälper det dig inte mycket heller av exakt samma anledningar.

Om du har råd med utrymmet och UPDATE/DELETE/INSERT overhead, skulle jag rekommendera att lägga till BTREE-indexet och låta MySQL bestämma vilket index han vill använda. Enligt min erfarenhet gör han vanligtvis ett mycket bra jobb med att välja rätt.

Jag hoppas att det besvarar din fråga.

EDIT: Som en sidoanteckning, se till att du väljer rätt storlek för ditt BTREE-index (i mitt exempel valde jag de första 10 rödingarna i staden). Detta gör uppenbarligen en enorm inverkan på kardinalitet. Om du valde stad(1) får du uppenbarligen en lägre kardinalitet än om du gjorde stad(10).

EDIT2: MySQL:s frågeplan (uppskattning) för vilket index som beskär flest poster är vad du ser i EXPLAIN.



  1. Varför genererar Entity Framework kapslade SQL-frågor?

  2. är PDO::PARAM_INT redundant?

  3. Avsluta MySQL utan att den startar om på El Capitan

  4. MYSQL skiftlägeskänslig sökning (med viloläge) för utf8