IN
jest pomiędzy =
i „zakres”. Więc spieram się z tytułem pytania. Dwa zakresy są praktycznie niemożliwe do zoptymalizowania; IN
plus zakres ma pewną szansę na optymalizację.
Na podstawie
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
Dostarczyłbym 2 indeksy i pozwoliłem Optymalizatorowi zdecydować, którego użyć:
INDEX(MarkedForDeletion, StartedAt, DeviceId)
INDEX(MarkedForDeletion, DeviceId, StartedAt)
Niektóre nowsze wersje MySQL/MariaDB potrafią przeskoczyć i wykorzystać wszystkie 3 kolumny w sekundzie indeks. We wszystkich wersjach pierwsze 2 kolumny każdego indeksu czynią go kandydatem. Wybór może być oparty na statystykach i może (lub nie) być „właściwym” wyborem.
Od AlarmId
nie może być NULL
, użyj wzorca:COUNT(*)
.
Po wprowadzeniu tej zmiany każdy z moich indeksów „zakrywa”, co daje dodatkowy wzrost wydajności.