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 ORDEM POR 3, 2, 1, 4
QUESTÕES
- 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?
SELECT *, FIELD(id,3,2,1,4) AS f FROM mytable WHERE id IN (3,2,1,4);
adicioneORDER BY f
ouORDER BY FIELD(id,3,2,1,4)
tente novamente.Respostas:
Para o registro
deve funcionar também porque você não precisa solicitar a lista na
WHERE
cláusulaQuanto à forma como funciona,
FIELD () é uma função que retorna a posição do índice de uma lista delimitada por vírgula 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 sofisticados
Por exemplo, usando a função IF ()
Isso fará com que os 4 primeiros IDs apareçam no topo da lista. Caso contrário, ele aparecerá na parte inferior. Por quê?
No
ORDER BY
, você recebe 0 ou 1.Vamos virar com DESC na primeira coluna
No
ORDER BY
, você ainda recebe 0 ou 1.SUA PERGUNTA REAL
Se você realmente quer informações internas sobre isso, vá para as páginas 189 e 192 do Livro.
para um mergulho profundo.
Em essência, há 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, até mesmo uma consulta contra uma única tabela é sempre processado como um join (Veja meu post Existe uma diferença entre a execução de uma condição de junção e uma condição em que? )O código fonte para tudo isso é
sql/sql_select.cc
Evidentemente, a
ORDER BY
árvore vai realizar 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 classificados enquanto carrega uma referência para a linha envolvida.fonte
N
valores em ambosIN
eFIELD
. Neste exemploN=4
. Entendo corretamente que esta consulta realizará pelo menos~N^2
operações. Porque cadaFIELD
cálculo faz~N
comparações uma vez para cada linha. Em caso afirmativo, isso é bastante lento para grandesN
talvez não seja uma abordagem muito boa?FIELD()
função deve ser umaO(1)
operação porqueFIELD()
possui um índice numéricoid
. Portanto, não vejo mais nada alémO(n)
de linhas. Não vejoFIELD()
nenhuma operação iterativa como aGREATEST()
necessária.FIELD
houverN
argumentos para comparar, ele executaráN
comparações. De que outra forma ele irá comparar um número comN
outros números, se não estiver fazendoO(N)
? A única possibilidade em que consigo pensar é em algum tipo de otimização por meio de uma estrutura de dados especial, como um hash ou uma árvore de argumentos. Na verdade eu sei queIN
tem essa otimização. Eu não seiFIELD
. O que você quer dizer com "índice numérico"?Talvez isso esteja muito longe do código real, portanto, o nível não é baixo o suficiente do que você queria:
Quando o MySQL não pode usar o índice para recuperar dados em ordem classificada, 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, envia essa tabela tmp para uma rotina "filesort" com informações sobre qual coluna classificar. Depois disso, as linhas estão na ordem de classificação, para selecioná-las uma a uma e retornar as colunas selecionadas.
fonte
FIELD
função é calculada. Receio que possa ter um impacto significativo no desempenho.