Como o MariaDB Otimiza Cláusulas ORDER BY
Em alguns casos o MariaDB pode utilizar índices para satisfazer uma requisição de ORDER BY ou GROUP BY sem fazer uma ordenação extra.
O índice também pode ser usado mesmo se o ORDER BY não coincidir exatamente com o índice, uma vez que todas as partes de índices não usadas e todos os extras na coluna ORDER BY são constantes na cláusula WHERE. A seguinte consulta usará o índice para resolver a parte ORDER BY / GROUP BY:
SELECT * FROM t1 ORDER BY key_part1,key_part2,... SELECT * FROM t1 WHERE key_part1=constante ORDER BY key_part2 SELECT * FROM t1 WHERE key_part1=constante GROUP BY key_part2 SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 DESC SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC,key_part2 DESC
Alguns casos onde o MariaDB não pode usar índices para resolver o ORDER BY: (Note que o MariaDB ainda usará índices para encontrar o registro que coincide com a cláusula WHERE):
- Você está fazendo um
ORDER BYem diferentes chaves:SELECT * FROM t1 ORDER BY key1,key2 - Você está fazendo um
ORDER BYusando partes de chaves não consecutivas.SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2 - Você está misturando
ASCeDESC.SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 ASC - As chaves usadas para buscar os registros são as mesmas usadas para fazer o
ORDER BY:SELECT * FROM t1 WHERE key2=constant ORDER BY key1 - Você está unindo muitas tabelas e as colunas nas quais você está fazendo um
ORDER BYnão são todas da primeira tabela que não éconste que é usada para retornar registros. (Esta é a primeira tabela na saída doEXPLAINque não usa um método de busca de registroconst). - Você tem diferentes expressões
ORDER BYeGROUP BY. - O índice da tabela usada é um tipo de índice que não armazena registros em ordem. (Como o índice
HASHem tabelsnHEAP).
Nestes casos onde o MariaDB tem que ordenar o resultado, ele usa o seguinte algoritmo:
- Lê todos os registros de acordo com a chave ou por uma varredura da tabela. Registros que não coincidem com a cláusula
WHEREsão saltados. - Armazena a chave ordenada em um buffer (de tamanho
sort_buffer). - Quando o buffer ficar cheio, execute ordeno-o e armazene o resultado em um arquivo temposrário. Salve um ponteiro para o bloco ordenado. (No caso de todos os regitros caberem no buffer ordenado, nenhum arquivo temporário é criado).
- Repete o armazenamento acima até todas as linhas tenham sido lidos.
- Faz um multi-merge até
MERGEBUFF(7) regiões para um bloco em outro arquivo temporário. Repete até que todos os blocos do primeiro arquivo estejam no segundo arquivo. - Repete o seguinte até que restem menos que
MERGEBUFF2(15) blocos. - No último multi-merge, só o ponteiro para o registro (última parte de chave ordenada) é escrito em um arquivo de resultado.
- Agora o código em
sql/records.ccserá usado para ler através deles ordenadamente usando os ponteiros de registro no arquivo resultante. Para otimização , lemos em um grande bloco de ponteiros de registros, ordena-os então lemos o registros ordenadamente de de um buffer de registro. (read_rnd_buffer_size) .
Você pode verificar com EXPLAIN SELECT ... ORDER BY se o MariaDB pode usar índices para resolver a consulta. Se você obtiver Using filesort na coluna extra, então o MariaDB não pode usar índices para resolver o ORDER BY. Leia "Sintaxe de EXPLAIN (Obter informações sobre uma SELECT)".
Se você quiser ter uma velocidade ORDER BY maior, primeiro você deve ver se você pode fazer que o MariaDB use índices em vez de fazer um fase de ordenação extra. Se não for possível, então você pode fazer:
- Aumente o tamanho da variável
sort_buffer_size. - Aumente o temenho da variável
read_rnd_buffer_size. - Altere
tmpdirpara apontar para um disco dedicado com muito espaço vazio. Se você usa o MariaDB ou posterior você pode distribuir a carga entre diversos discos físicos definindotmpdircom uma lista de caminhos separados por dois pontos:(ponto e vírgula;no Windows). Eles serão usados de acordo com o método round-robin. Nota: Estes caminho devem estar em diferentes discos físicos, e não em diferentes partições do mesmo disco.
Por padrão, o MariaDB ordena todas as consultas GROUP BY x,y[,...] como se você tivesse especificado ORDER BY x,y[,...]. Se você incluir a cláusula ORDER BY explicitamente, o MariaDB a otimizará sem qualquer penalidade na velocidade, embora a ordenacao ainda ocorra. Se a consulta inclui um GROUP BY mas você deseja evitar a sobrecarga da ordenar o resultado, você pode suprimir a ordenacao especificando ORDER BY NULL: