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.