sql >> Database >  >> RDS >> Mysql

Correcte indexering bij gebruik van OR-operator

U begrijpt niet hoe indexen werken.

Denk aan een telefoonboek (het equivalent van een index met twee kolommen op achternaam eerst, voornaam als laatste). Als ik u vraag om alle mensen in het telefoonboek te vinden wiens achternaam "Smith" is, kunt u profiteren van het feit dat de namen op die manier zijn gerangschikt; je kunt er vanuit gaan dat de Smiths samen georganiseerd zijn. Maar als ik je vraag om alle mensen te vinden wiens voornaam "John" is, krijg je geen voordeel van de index. Johns kan elke achternaam hebben, en daarom zijn ze verspreid over het boek en moet je uiteindelijk de moeilijke weg zoeken, van kaft tot kaft.

Als ik je nu vraag om alle mensen te vinden wiens achternaam "Smith" is OF wiens voornaam "John" is, dan kun je de Smiths gemakkelijk vinden zoals voorheen, maar dat helpt je helemaal niet om de Johns te vinden. Ze zijn nog steeds verspreid door het boek en je moet ze op de harde manier zoeken.

Hetzelfde geldt voor indexen met meerdere kolommen in SQL. De index wordt gesorteerd op de eerste kolom, vervolgens gesorteerd op de tweede kolom in het geval van gelijken in de eerste kolom, vervolgens gesorteerd op de derde kolom in het geval van gelijken in zowel de eerste twee kolommen, enz. Het is niet gesorteerd op alle kolommen tegelijkertijd. Uw index met meerdere kolommen helpt dus niet om uw zoektermen efficiënter te maken, behalve de meest linkse kolom in de index.

Terug naar je oorspronkelijke vraag.

Maak voor elke kolom een ​​afzonderlijke index met één kolom. Een van deze indexen is een betere keuze dan de andere, gebaseerd op MySQL's schatting van het aantal I/O-bewerkingen de index zal oplopen als deze wordt gebruikt.

Moderne versies van MySQL hebben ook wat slimmigheden over indexmerging , dus de zoekopdracht mag gebruik meer dan één index in een bepaalde tabel en probeer vervolgens de resultaten samen te voegen. Anders is MySQL meestal beperkt tot het gebruik van één index per tabel in een bepaalde zoekopdracht.

Een andere truc die veel mensen met succes gebruiken, is om een ​​afzonderlijke zoekopdracht uit te voeren voor elk van uw geïndexeerde kolommen (die de respectieve index zouden moeten gebruiken) en vervolgens UNION de 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' 

Nog een laatste opmerking:als je merkt dat je op zoek bent naar hetzelfde 'something' over vier velden, moet je heroverwegen of alle vier de velden eigenlijk hetzelfde zijn, en je schuldig bent aan het ontwerpen van een tabel die schendt de eerste normale vorm met herhalende groepen . Zo ja, misschien horen veld1 tot en met veld4 in een enkele kolom in een onderliggende tabel. Dan wordt het een stuk eenvoudiger om te indexeren en te zoeken:

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


  1. GROUP en COUNT() leeftijden in CakePHP

  2. Mysql-retourclausule equivalent

  3. Hoe specificeer je de IN-component in een dynamische query met behulp van een variabele?

  4. Waarom negeert de SQL Server automatisch de lege ruimte aan het einde?