sql >> Database >  >> RDS >> Mysql

Hoe moet ik indexeren voor een query met twee bereikvoorwaarden?

IN ligt een beetje tussen = en een 'bereik'. Dus ik kibbel met de titel van de vraag. Twee bereiken is vrijwel onmogelijk te optimaliseren; een IN plus een bereik heeft enige kans op optimalisatie.

Gebaseerd op

WHERE `StartedAt` >= FROM_UNIXTIME(1518990000)  
AND   `StartedAt` <  FROM_UNIXTIME(1518998400) 
AND `DeviceId` IN (
    UNHEX('00030000000000000000000000000000'),
    UNHEX('000300000000000000000000000181cd'),
    UNHEX('000300000000000000000000000e7cf6'),
    UNHEX('000300000000000000000000000e7cf7'),
    UNHEX('000300000000000000000000000f423f')
) AND `MarkedForDeletion` = FALSE

Ik zou 2 indexen geven en de Optimizer laten beslissen welke te gebruiken:

INDEX(MarkedForDeletion, StartedAt, DeviceId)
INDEX(MarkedForDeletion, DeviceId, StartedAt)

Sommige nieuwere versies van MySQL/MariaDB kunnen overspringen en gebruik maken van alle 3 de kolommen in de tweede inhoudsopgave. In alle versies maken de eerste 2 kolommen van beide indexen het een kandidaat. De keuze kan worden bepaald door statistieken en kan (of niet) de 'juiste' keuze zijn.

Sinds AlarmId kan niet NULL zijn , gebruik het patroon:COUNT(*) .

Nadat ik die wijziging heb aangebracht, is elk van mijn indexen "bedekt", waardoor de prestaties een extra boost krijgen.



  1. Oracle SQL - max() met NULL-waarden

  2. Trigger om invoeging te voorkomen voor dubbele gegevens van twee kolommen

  3. Maak verbinding met MySql db via SSH in Netbeans

  4. Oracle Doorzoek alle tabellen alle kolommen op string