U kunt in dit geval geen index gebruiken, omdat u een RANGE
. gebruikt filterconditie.
Als je zoiets zou gebruiken als:
SELECT *
FROM values_table this_
WHERE this_.value1 = @value
ORDER BY
value2
LIMIT 10
en maak vervolgens een samengestelde index op (VALUE1, VALUE2)
zou zowel voor filteren als voor bestellen worden gebruikt.
Maar je gebruikt een bereikconditie, daarom moet je toch bestellen.
Uw samengestelde index ziet er als volgt uit:
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
, en als u 1
. selecteert en 2
in value1
, krijg je nog steeds geen hele gesorteerde set van value2
.
Als uw index op value2
is niet erg selectief (d.w.z. er zijn niet veel DISTINCT value2
in de tabel), kunt u proberen:
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
Dit heet een SKIP SCAN
toegangsmethode. MySQL
ondersteunt het niet rechtstreeks, maar het kan op deze manier worden nagebootst.
Het RANGE
in dit geval wordt toegang gebruikt, maar waarschijnlijk krijgt u geen prestatievoordeel tenzij DISTINCT value2
minder dan ongeveer 1%
bevatten aantal rijen.
Opmerking gebruik van:
m.value2 >= q.value2
AND m.value2 <= q.value2
in plaats van
m.value2 = q.value2
Dit maakt MySQL
voer RANGE
uit elke lus controleren.