sql >> Database >  >> RDS >> Mysql

MySQL:samengestelde index fulltext+btree?

Gebruik IN BOOLEAN MODE .

De datumindex is niet nuttig. Er is geen manier om de twee indexen te combineren.

Pas op, als een gebruiker zoekt naar iets dat wordt weergegeven in 30K-rijen, zal de zoekopdracht traag zijn. Er is geen eenvoudige manier omheen.

Ik vermoed dat je een TEXT . hebt kolom in de tabel? Als dat zo is, is er hoop. In plaats van blindelings SELECT * te doen , laten we eerst de id's zoeken en de LIMIT . ophalen toegepast, dan doe de * .

SELECT a.* 
    FROM tbl AS a
    JOIN ( SELECT date, id
             FROM tbl
             WHERE MATCH(...) AGAINST (...)
             ORDER BY date DESC
             LIMIT 10 ) AS x
        USING(date, id)
    ORDER BY date DESC;

Samen met

PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)

Deze formulering en indexering zouden als volgt moeten werken:

  1. Gebruik FULLTEXT om 30K rijen te vinden, lever de PK.
  2. Met de PK sorteert u 30K rijen op date .
  3. Kies de laatste 10 en lever date, id
  4. Reik 10 keer terug in de tafel met de PK.
  5. Sorteer opnieuw. (Ja, dit is nodig.)

Meer (Als reactie op een overvloed aan opmerkingen):

Het doel achter mijn herformulering is om te voorkomen dat ik alles ophaal kolommen van 30K rijen. In plaats daarvan haalt het alleen de PRIMARY KEY . op , verkleint dat vervolgens tot 10 en haalt vervolgens * . op slechts 10 rijen. Veel minder spullen schuiven.

Over COUNT op een InnoDB-tafel:

  • INDEX(col) zorgt ervoor dat een index scan werkt voor SELECT COUNT(*) of SELECT COUNT(col) zonder een WHERE .
  • Zonder INDEX(col), SELECT COUNT(*)will use the "smallest" index; but SELECT COUNT(col)` heeft een tabel nodig scannen.
  • Een tabelscan is meestal langzamer dan een indexscan.
  • Wees voorzichtig met timing -- Het wordt aanzienlijk beïnvloed door de vraag of de index en/of tabel al in het RAM-geheugen is opgeslagen.

Nog iets over FULLTEXT is de + voor woorden -- om te zeggen dat elk woord moet bestaan, anders is er geen overeenkomst. Dit kan de 30K verminderen.

De FULLTEXT index levert de date, id is willekeurige volgorde, niet PK-volgorde. Hoe dan ook, het is 'fout' om een ​​bestelling aan te nemen, daarom is het 'goed' om ORDER BY toe te voegen en laat de Optimizer het dan weggooien als het weet dat het overbodig is. En soms kan de Optimizer profiteren van de ORDER BY (niet in jouw geval).

Alleen de ORDER BY . verwijderen zorgt er in veel gevallen voor dat een query veel sneller wordt uitgevoerd. Dit komt omdat het voorkomt dat bijvoorbeeld 30K rijen worden opgehaald en gesorteerd. In plaats daarvan levert het gewoon "elke" 10 rijen.

(Ik heb geen ervaring met Postgres, dus ik kan die vraag niet beantwoorden.)




  1. Hoe de CONCAT()-functie werkt in PostgreSQL

  2. WordPress 5 installeren op ZEIT Nu met MySQL Hosting

  3. Verwijderen uit een MySQL-tabel met beperkingen voor externe sleutels

  4. Tips voor het bewaken van MariaDB-replicatie met ClusterControl