AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 109120
Accepted
itz_nsn
itz_nsn
Asked: 2015-08-06 11:52:31 +0800 CST2015-08-06 11:52:31 +0800 CST 2015-08-06 11:52:31 +0800 CST

Como ORDER BY FIELD() no MySQL funciona internamente

  • 772

Eu entendo como a ORDER BYclá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?
mysql order-by
  • 2 2 respostas
  • 173154 Views

2 respostas

  • Voted
  1. Best Answer
    RolandoMySQLDBA
    2015-08-06T12:28:49+08:002015-08-06T12:28:49+08:00

    Para o registro

    SELECT * FROM mytable WHERE id IN (1,2,3,4) ORDER BY FIELD(id,3,2,1,4);
    

    deve funcionar também porque você não precisa ordenar a lista na WHEREcláusula

    Quanto 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.

      • SE id = 1, então FIELD(id,3,2,1,4) retorna 3 (posição onde 1 está na lista)
      • SE id = 2, então FIELD(id,3,2,1,4) retorna 2 (posição onde 2 está na lista)
      • SE id = 3, então FIELD(id,3,2,1,4) retorna 1 (posição onde 3 está na lista)
      • SE id = 4, então FIELD(id,3,2,1,4) retorna 4 (posição onde 4 está na lista)
      • IF id = qualquer outra coisa, então FIELD(id,3,2,1,4) retorna 0 (não está na lista)
    • Os ORDER BYvalores são avaliados pelo que FIELD() retorna

    Você pode criar todos os tipos de pedidos extravagantes

    Por exemplo, usando a função IF()

    SELECT * FROM mytable
    WHERE id IN (1,2,3,4)
    ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0),FIELD(id,3,2,1,4);
    

    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.

    • Se a primeira coluna for 0, faça com que qualquer um dos 4 primeiros ids apareça
    • Se a primeira coluna for 1, faça-a aparecer depois

    Vamos inverter com DESC na primeira coluna

    SELECT * FROM mytable
    WHERE id IN (1,2,3,4)
    ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0) DESC,FIELD(id,3,2,1,4);
    

    No ORDER BY, você ainda obtém 0 ou 1.

    • Se a primeira coluna for 1, faça qualquer coisa, menos os 4 primeiros ids aparecerem.
    • Se a primeira coluna for 0, faça com que os primeiros 4 ids apareçam na ordem original

    SUA PERGUNTA REAL

    Se você realmente quer detalhes internos sobre isso, vá para as páginas 189 e 192 do Livro

    Internos do MySQL

    para um verdadeiro mergulho profundo.

    Em essência, existe uma classe C++ chamada ORDER *order(A ORDER BYárvore de expressão). In JOIN::prepare, *orderé usado em uma função chamada setup_order(). Por que no meio da JOINaula? 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 de FIELD(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.

    • 98
  2. jkavalik
    2015-08-06T12:28:04+08:002015-08-06T12:28:04+08:00

    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.

    • 1

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve