Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL não usando índices (usando filesort) ao usar ORDER BY


Você não pode usar um índice neste caso, pois usa um RANGE condição de filtragem.

Se você usar algo como:
SELECT  *
FROM    values_table this_
WHERE   this_.value1 = @value
ORDER BY
        value2
LIMIT 10

, criando um índice composto em (VALUE1, VALUE2) seria usado tanto para filtrar quanto para ordenar.

Mas você usa uma condição de alcance, é por isso que você precisará realizar o pedido de qualquer maneira.

Seu índice composto ficará assim:
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 você selecionar 1 e 2 em value1 , você ainda não obtém um conjunto classificado inteiro de value2 .

Se o seu índice em value2 não é muito seletivo (ou seja, não há muitos DISTINCT value2 na tabela), você pode tentar:
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

Isso é chamado de SKIP SCAN método de acesso. MySQL não o suporta diretamente, mas pode ser emulado assim.

O RANGE access será usado neste caso, mas provavelmente você não obterá nenhum benefício de desempenho a menos que DISTINCT value2 compreendem menos de cerca de 1% de filas.

Observe o uso de:
m.value2 >= q.value2
AND m.value2 <= q.value2

ao invés de
m.value2 = q.value2

Isso torna o MySQL execute RANGE verificando em cada loop.