Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment dois-je procéder pour indexer une requête avec deux conditions de plage ?

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.