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.