Vous ne pouvez pas utiliser un index dans ce cas, car vous utilisez un RANGE
condition de filtrage.
Si vous utilisez quelque chose comme :
SELECT *
FROM values_table this_
WHERE this_.value1 = @value
ORDER BY
value2
LIMIT 10
, puis création d'un index composite sur (VALUE1, VALUE2)
serait utilisé à la fois pour le filtrage et pour la commande.
Mais vous utilisez une condition à distance, c'est pourquoi vous devrez quand même effectuer une commande.
Votre index composite ressemblera à ceci :
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
, et si vous sélectionnez 1
et 2
dans value1
, vous n'obtenez toujours pas un ensemble trié complet de value2
.
Si votre index sur value2
n'est pas très sélectif (c'est-à-dire qu'il n'y a pas beaucoup de DISTINCT value2
dans le tableau), vous pouvez essayer :
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
C'est ce qu'on appelle un SKIP SCAN
Méthode d'accès. MySQL
ne le supporte pas directement, mais il peut être émulé comme ceci.
La RANGE
l'accès sera utilisé dans ce cas, mais vous n'obtiendrez probablement aucun avantage en termes de performances à moins que DISTINCT value2
représentent moins d'environ 1%
de lignes.
Notez l'utilisation de :
m.value2 >= q.value2
AND m.value2 <= q.value2
au lieu de
m.value2 = q.value2
Cela rend MySQL
effectuer RANGE
vérification sur chaque boucle.