Eu entendo como a ORDER BY
cláusula funciona e como a FIELD()
função funciona. O que eu quero entender é como os dois trabalham juntos para classificar. Como as linhas são recuperadas e como a ordem de classificação é derivada
+----+---------+
| id | name |
+----+---------+
| 1 | stan |
| 2 | kyle |
| 3 | kenny |
| 4 | cartman |
+----+---------+
SELECT * FROM mytable WHERE id IN (3,2,1,4) ORDER BY FIELD(id,3,2,1,4)
A consulta acima resultará em
+----+---------+
| id | name |
+----+---------+
| 3 | kenny |
| 2 | kyle |
| 1 | stan |
| 4 | cartman |
+----+---------+
algo semelhante a dizer ORDER BY 3, 2, 1, 4
PERGUNTAS
- Como isso funciona internamente?
- Como o MySQL obtém as linhas e calcula a ordem de classificação?
- Como o MySQL sabe que precisa classificar pela coluna id?
Para o registro
deve funcionar também porque você não precisa ordenar a lista na
WHERE
cláusulaQuanto a como funciona,
FIELD() é uma função que retorna a posição do índice de uma lista delimitada por vírgulas se o valor que você está procurando existir.
Os
ORDER BY
valores são avaliados pelo que FIELD() retornaVocê pode criar todos os tipos de pedidos extravagantes
Por exemplo, usando a função IF()
Isso fará com que os primeiros 4 ids apareçam no topo da lista, caso contrário, ele aparecerá na parte inferior. Por quê?
No
ORDER BY
, você obtém 0 ou 1.Vamos inverter com DESC na primeira coluna
No
ORDER BY
, você ainda obtém 0 ou 1.SUA PERGUNTA REAL
Se você realmente quer detalhes internos sobre isso, vá para as páginas 189 e 192 do Livro
para um verdadeiro mergulho profundo.
Em essência, existe uma classe C++ chamada
ORDER *order
(AORDER BY
árvore de expressão). InJOIN::prepare
,*order
é usado em uma função chamadasetup_order()
. Por que no meio daJOIN
aula? Cada consulta, mesmo uma consulta em uma única tabela é sempre processada como um JOIN (Veja meu post Existe uma diferença de execução entre uma condição JOIN e uma condição WHERE? )O código fonte de tudo isso é
sql/sql_select.cc
Evidentemente, a
ORDER BY
árvore vai manter a avaliação deFIELD(id,3,2,1,4)
. Assim, os números 0,1,2,3,4 são os valores que estão sendo ordenados enquanto carregam uma referência para a linha envolvida.Talvez isso esteja muito longe do código real, portanto, não é baixo o suficiente para o que você queria:
Quando o MySQL não pode usar o índice para recuperar dados em ordem de classificação, ele cria uma tabela/conjunto de resultados temporário com todas as colunas selecionadas e alguns dados adicionais - um deles é algum tipo de coluna para armazenar os resultados do valor da expressão ORDER BY para cada linha - em seguida, ele envia esta tabela tmp para uma rotina "filesort" com informações de qual coluna classificar. Depois disso, as linhas estão em ordem de classificação para que ele possa selecioná-las uma a uma e retornar as colunas selecionadas.