IN
liegt sozusagen zwischen =
und eine "Reichweite". Also streite ich mit dem Titel der Frage. Zwei Bereiche zu optimieren ist praktisch unmöglich; ein IN
plus eine Reihe hat eine Chance auf Optimierung.
Basierend auf
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
Ich würde 2 Indizes bereitstellen und den Optimierer entscheiden lassen, welcher verwendet werden soll:
INDEX(MarkedForDeletion, StartedAt, DeviceId)
INDEX(MarkedForDeletion, DeviceId, StartedAt)
Einige neuere Versionen von MySQL/MariaDB können alle 3 Spalten in der zweiten überspringen und verwenden Index. In allen Versionen machen die ersten 2 Spalten jedes Indexes ihn zu einem Kandidaten. Die Wahl kann von Statistiken bestimmt werden und kann (oder auch nicht) die „richtige“ Wahl sein.
Seit AlarmId
darf nicht NULL
sein , verwenden Sie das Muster:COUNT(*)
.
Nach dieser Änderung ist jeder meiner Indizes "deckend", wodurch die Leistung zusätzlich gesteigert wird.