sql >> Database >  >> RDS >> Mysql

Fulltext en samengestelde indexen en hoe deze de zoekopdracht beïnvloeden

Als ik je vraag begrijp, weet je dat de MATCH AGAINST je FULLTEXT-index gebruikt en je vraagt ​​je af hoe MySQL de rest van de WHERE-component toepast (dwz doet het een tablescan of een geïndexeerde lookup).

Dit is wat ik aanneem over je tabel:het heeft een PRIMAIRE SLEUTEL in een id-kolom en de FULLTEXT-index.

Dus allereerst zal MySQL nooit gebruik de FULLTEXT-index voor de WHERE-clausule stad/staat. Waarom? Omdat FULLTEXT-indexen alleen van toepassing zijn bij MATCH AGAINST. Zie hier in de alinea na de eerste reeks opsommingstekens (niet de opsommingstekens in de inhoudsopgave).

BEWERKEN: In uw geval, ervan uitgaande dat uw tabel niet slechts 10 rijen heeft, past MySQL de FULLTEXT-index toe voor uw MATCH AGAINST en voert vervolgens een tabelscan uit op die resultaten om de stad/staat WAAR toe te passen.

Dus wat als u een BTREE-index toevoegt aan stad en staat?

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

Nou, MySQL kan er maar één gebruiken index voor deze query, omdat het een eenvoudige selectie is. Het zal ofwel gebruik de FULLTEXT of de BTREE. Merk op dat als ik één index zeg, ik één indexdefinitie bedoel, niet één kolom in een meerdelige index. Anwway, dit roept dan de vraag op welke doet het gebruikt?

Dat hangt af van de tabelanalyse. MySQL zal proberen te schatten (gebaseerd op tabelstatistieken van de laatste OPTIMALISEERTABEL) welke index de meeste records zal snoeien. Als de stad/staat WHERE je naar 10 records haalt terwijl de MATCH AGAINST je slechts naar 100 haalt, dan gebruikt MySQL de city__state index eerst voor de stad/staat WAAR en doe dan een tafelscan voor de MATCH TEGEN.

Aan de andere kant, als de MATCH_AGAINST je terugbrengt naar 10 records terwijl de stad/staat WHERE je terugbrengt naar slechts 1000, dan zal MySQL eerst de FULLTEXT-index toepassen en tabellen scannen voor stad en staat.

De bottom line is de kardinaliteit van uw index. Hoe uniek zijn in wezen de waarden die in uw index worden opgenomen? Als voor elk record in je tabel de stad is ingesteld op Oakland, dan is het geen erg unieke sleutel en heeft dus city ='Oakland' vermindert het aantal records niet echt voor u. In dat geval zeggen we dat uw city__state-index een lage kardinaliteit heeft .

Dus als 90% van de woorden in je FULLTEXT-index "John" zijn, dan helpt dat je ook niet echt om precies dezelfde redenen.

Als u zich de ruimte en de UPDATE/DELETE/INSERT overhead kunt veroorloven, raad ik u aan de BTREE-index toe te voegen en MySQL te laten beslissen welke index hij wil gebruiken. In mijn ervaring doet hij het meestal erg goed om de juiste te kiezen.

Ik hoop dat dat je vraag beantwoordt.

BEWERKEN: Even terzijde, ervoor zorgend dat je de juiste maat kiest voor je BTREE-index (in mijn voorbeeld heb ik de eerste 10 tekens in de stad gekozen). Dit heeft duidelijk een enorme impact op de kardinaliteit. Als je stad(1) hebt gekozen, krijg je natuurlijk een lagere kardinaliteit dan als je stad (10) hebt gekozen.

EDIT2: Het zoekplan (schatting) van MySQL voor welke index de meeste records snoeit, is wat u ziet in EXPLAIN.



  1. Declareer syntaxisfout in MYSQL Workbench

  2. Wanneer en hoe de SQL PARTITION BY-clausule te gebruiken?

  3. Nog een argument voor opgeslagen procedures

  4. Mac OS X - EnvironmentError:mysql_config niet gevonden