Du kan inte använda ett index i det här fallet, eftersom du använder en RANGE
filtreringsvillkor.
Om du skulle använda något som:
SELECT *
FROM values_table this_
WHERE this_.value1 = @value
ORDER BY
value2
LIMIT 10
, och skapa sedan ett sammansatt index på (VALUE1, VALUE2)
skulle användas både för filtrering och för beställning.
Men du använder ett avståndsvillkor, det är därför du måste utföra beställning ändå.
Ditt sammansatta index kommer att se ut så här:
value1 value2 ----- ------ 1 10 1 20 1 30 1 40 1 50 1 60 2 10 2 20 2 30 3 10 3 20 3 30 3 40
, och om du väljer 1
och 2
i value1
, du får fortfarande inte en hel sorterad uppsättning av value2
.
Om ditt index på value2
är inte särskilt selektiv (dvs. det finns inte många DISTINCT value2
i tabellen), kan du prova:
CREATE INDEX ix_table_value2_value1 ON mytable (value2, value1)
/* Note the order, it's important */
SELECT *
FROM (
SELECT DISTINCT value2
FROM mytable
ORDER BY
value2
) q,
mytable m
WHERE m.value2 >= q.value2
AND m.value2 <= q.value2
AND m.value1 BETWEEN 13123123 AND 123123123
Detta kallas en SKIP SCAN
åtkomstmetod. MySQL
stöder det inte direkt, men det kan emuleras så här.
RANGE
åtkomst kommer att användas i det här fallet, men förmodligen kommer du inte att få någon prestandafördel om inte DISTINCT value2
omfattar mindre än ungefär 1%
rader.
Notera användning av:
m.value2 >= q.value2
AND m.value2 <= q.value2
istället för
m.value2 = q.value2
Detta gör MySQL
utför RANGE
kontrollerar varje slinga.