Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL non utilizza gli indici (Utilizzo di filesort) quando si utilizza ORDER BY

Non è possibile utilizzare un indice in questo caso, poiché si utilizza un RANGE condizione di filtraggio.

Se dovessi usare qualcosa come:

SELECT  *
FROM    values_table this_
WHERE   this_.value1 = @value
ORDER BY
        value2
LIMIT 10

, quindi creando un indice composito su (VALUE1, VALUE2) verrebbe utilizzato sia per il filtraggio che per l'ordinazione.

Ma utilizzi una condizione a intervalli, ecco perché dovrai comunque eseguire l'ordine.

Il tuo indice composito sarà simile a questo:

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

e se selezioni 1 e 2 in value1 , non ottieni ancora un intero set ordinato di value2 .

Se il tuo indice su value2 non è molto selettivo (cioè non ci sono molti DISTINCT value2 nella tabella), potresti provare:

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

Questo è chiamato SKIP SCAN metodo di accesso. MySQL non lo supporta direttamente, ma può essere emulato in questo modo.

Il RANGE in questo caso verrà utilizzato l'accesso, ma probabilmente non otterrai alcun vantaggio in termini di prestazioni a meno che non DISTINCT value2 comprendono meno di circa 1% di righe.

Nota l'utilizzo di:

m.value2 >= q.value2
AND m.value2 <= q.value2

invece di

m.value2 = q.value2

Questo rende MySQL eseguire RANGE controllando ogni ciclo.