sql >> Databasteknik >  >> RDS >> Mysql

Korrekt indexering när du använder OR-operator

Du missförstår hur index fungerar.

Tänk på en telefonbok (motsvarande ett tvåkolumnsregister på efternamn för, förnamn efter). Om jag ber dig hitta alla personer i telefonboken vars efternamn är "Smith" kan du dra nytta av att namnen är ordnade på det sättet; du kan anta att Smiths är organiserade tillsammans. Men om jag ber dig hitta alla personer vars förnamn är "John" får du ingen nytta av indexet. Johns kan ha vilket efternamn som helst, så de är utspridda i hela boken och det slutar med att du måste söka den hårda vägen, från pärm till pärm.

Om jag nu ber dig att hitta alla personer vars efternamn är "Smith" ELLER vars förnamn är "John", kan du hitta Smiths lätt som tidigare, men det hjälper dig inte alls att hitta Johns. De är fortfarande utspridda i boken och du måste söka efter dem den hårda vägen.

Det är samma sak med index med flera kolumner i SQL. Indexet sorteras efter den första kolumnen, sedan sorteras efter den andra kolumnen i fall av liknande i första kolumnen, sedan sorteras efter den tredje kolumnen i fall av kopplingar i båda de två första kolumnerna, etc. Det sorteras inte efter alla kolumner samtidigt. Så ditt index med flera kolumner hjälper inte till att göra dina söktermer effektivare, förutom kolumnen längst till vänster i indexet.

Tillbaka till din ursprungliga fråga.

Skapa ett separat index med en kolumn för varje kolumn. Ett av dessa index kommer att vara ett bättre val än de andra, baserat på MySQL:s uppskattning av hur många I/O-operationer indexet uppstår om det används.

Moderna versioner av MySQL har också en del smartheter om indexsammanslagning , så frågan kan använd mer än ett index i en given tabell och försök sedan slå samman resultaten. Annars tenderar MySQL att vara begränsad till att använda ett index per tabell i en given fråga.

Ett annat knep som många använder framgångsrikt är att göra en separat fråga för var och en av dina indexerade kolumner (som ska använda respektive index) och sedan UNION resultaten.

SELECT fields FROM table WHERE field1='something' 
UNION
SELECT fields FROM table WHERE field2='something' 
UNION
SELECT fields FROM table WHERE field3='something' 
UNION
SELECT fields FROM table WHERE field4='something' 

En sista observation:om du hittar dig själv att söka efter samma 'something' över fyra fält bör du ompröva om alla fyra fälten faktiskt är samma sak, och du gör dig skyldig till att utforma en tabell som bryter mot First Normal form med upprepade grupper . Om så är fallet, kanske fält1 till fält4 hör hemma i en enda kolumn i en underordnad tabell. Då blir det mycket lättare att indexera och fråga:

SELECT fields from table INNER JOIN child_table ON table.pk = child_table.fk
WHERE child_table.field = 'something'


  1. COMMIT OR conn.setAutoCommit(true)

  2. Använder Prepared Statement i C# med Mysql

  3. UML-notation

  4. Hur Round() fungerar i PostgreSQL