Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como devo proceder para indexar uma consulta com duas condições de intervalo?


IN é uma espécie de entre = e um 'intervalo'. Então, eu brinco com o título da pergunta. Duas faixas são praticamente impossíveis de otimizar; um IN mais um intervalo tem alguma chance de otimização.

Baseado em
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

Eu forneceria 2 índices e deixaria o Optimizer decidir qual usar:
INDEX(MarkedForDeletion, StartedAt, DeviceId)
INDEX(MarkedForDeletion, DeviceId, StartedAt)

Algumas versões mais recentes do MySQL/MariaDB podem saltar e fazer uso de todas as 3 colunas no segundo índice. Em todas as versões, as 2 primeiras colunas de qualquer índice o tornam um candidato. A escolha pode ser motivada por estatísticas e pode (ou não) ser a escolha 'certa'.

Desde AlarmId não pode ser NULL , use o padrão:COUNT(*) .

Depois de fazer essa alteração, cada um dos meus índices está "cobrindo", dando assim um impulso extra no desempenho.