IN
est en quelque sorte entre =
et une "gamme". Donc, je chipote avec le titre sur la question. Deux gammes est pratiquement impossible à optimiser; un IN
plus une plage a des chances d'être optimisée.
Basé sur
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
Je fournirais 2 index et laisserais l'optimiseur décider lequel utiliser :
INDEX(MarkedForDeletion, StartedAt, DeviceId)
INDEX(MarkedForDeletion, DeviceId, StartedAt)
Certaines versions plus récentes de MySQL/MariaDB peuvent sauter et utiliser les 3 colonnes dans la seconde indice. Dans toutes les versions, les 2 premières colonnes de chaque index en font un candidat. Le choix peut être motivé par des statistiques et peut (ou non) être le "bon" choix.
Depuis AlarmId
ne peut pas être NULL
, utilisez le modèle :COUNT(*)
.
Après avoir effectué ce changement, chacun de mes index est « couvrant », ce qui améliore encore les performances.