sql >> Databasteknik >  >> RDS >> Mysql

MySQL:sammansatt index fulltext+btree?

Använd IN BOOLEAN MODE .

Datumindexet är inte användbart. Det finns inget sätt att kombinera de två indexen.

Se upp, om en användare söker efter något som dyker upp i 30 000 rader, kommer sökningen att vara långsam. Det finns ingen enkel väg runt det.

Jag misstänker att du har en TEXT kolumn i tabellen? I så fall finns det hopp. Istället för att blint göra SELECT * , låt oss först hitta ID:n och få LIMIT tillämpas, gör * .

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;

Tillsammans med

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

Denna formulering och indexering bör fungera så här:

  1. Använd FULLTEXT för att hitta 30 000 rader, leverera PK.
  2. Med PK, sortera 30 000 rader efter date .
  3. Välj de sista 10, leverera date, id
  4. Räck tillbaka till tabellen 10 gånger med hjälp av PK.
  5. Sortera igen. (Ja, det här är nödvändigt.)

Mer (Svar på en uppsjö av kommentarer):

Målet bakom min omformulering är att undvika att hämta alla kolumner på 30 000 rader. Istället hämtar den bara PRIMARY KEY , drar sedan ner det till 10 och hämtar sedan * endast 10 rader. Mycket mindre saker skottas runt.

Angående COUNT på en InnoDB-tabell:

  • INDEX(kol) gör det så att ett index skanningen fungerar för SELECT COUNT(*) eller SELECT COUNT(col) utan en WHERE .
  • Utan INDEX(col), SELECT COUNT(*)will use the "smallest" index; but SELECT COUNT(col)` kommer att behöva en tabell skanna.
  • En tabellskanning är vanligtvis långsammare än en indexsökning.
  • Var försiktig med timing -- Det påverkas avsevärt av om indexet och/eller tabellen redan är cachad i RAM.

En annan sak med FULLTEXT är + framför ord -- att säga att varje ord måste existera, annars finns det ingen matchning. Detta kan dra ner på 30K.

FULLTEXT index kommer att leverera date, id är slumpmässig ordning, inte PK-ordning. Hur som helst, det är "fel" att anta någon beställning, därför är det "rätt" att lägga till ORDER BY , låt sedan Optimizer slänga den om den vet att det är överflödigt. Och ibland kan optimeraren dra fördel av ORDER BY (inte i ditt fall).

Tar bara bort ORDER BY , i många fall, gör att en fråga körs mycket snabbare. Detta beror på att det undviker att hämta till exempel 30K rader och sortera dem. Istället levererar den helt enkelt "vilka som helst" 10 rader.

(Jag har ingen erfarenhet av Postgres, så jag kan inte svara på den frågan.)




  1. Om RM-formatelementet i Oracle

  2. Varför har heltal i databasradtuppel ett 'L'-suffix?

  3. Använder du .aggregate() på ett värde som introducerats med .extra(select={...}) i en Django-fråga?

  4. Skapa en kall standby för PostgreSQL med Amazon AWS