Entiendo cómo ORDER BY
funciona la cláusula y cómo FIELD()
funciona la función. Lo que quiero entender es cómo ambos trabajan juntos para clasificar. Cómo se recuperan las filas y cómo se deriva el orden de clasificación
+----+---------+
| 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)
La consulta anterior dará como resultado
+----+---------+
| id | name |
+----+---------+
| 3 | kenny |
| 2 | kyle |
| 1 | stan |
| 4 | cartman |
+----+---------+
algo similar a decir ORDER BY 3, 2, 1, 4
PREGUNTAS
- ¿Cómo funciona esto internamente?
- ¿Cómo obtiene MySQL las filas y calcula el orden de clasificación?
- ¿Cómo sabe MySQL que tiene que ordenar por la columna id?
SELECT *, FIELD(id,3,2,1,4) AS f FROM mytable WHERE id IN (3,2,1,4);
luego agregueORDER BY f
oORDER BY FIELD(id,3,2,1,4)
e intente nuevamente.Respuestas:
Para el registro
debería funcionar bien porque no tiene que ordenar la lista en la
WHERE
cláusulaEn cuanto a cómo funciona,
CAMPO() es una función que devuelve la posición del índice de una lista delimitada por comas si el valor que está buscando existe.
Los
ORDER BY
valores son evaluados por qué CAMPO () devuelvePuedes crear todo tipo de pedidos elegantes
Por ejemplo, usando la función IF ()
Esto hará que los primeros 4 identificadores aparezcan en la parte superior de la lista, de lo contrario, aparecerá en la parte inferior. ¿Por qué?
En el
ORDER BY
, obtienes 0 o 1.Volteemos con DESC en la primera columna
En el
ORDER BY
, todavía obtienes 0 o 1.TU PREGUNTA REAL
Si realmente quieres cosas internas sobre esto, ve a las páginas 189 y 192 del Libro
para una verdadera inmersión profunda.
En esencia, hay una clase de C ++ llamada
ORDER *order
(ElORDER BY
árbol de expresión). EnJOIN::prepare
,*order
se usa en una función llamadasetup_order()
. ¿Por qué en medio de laJOIN
clase? Cada consulta, incluso una consulta en una sola tabla siempre se procesa como JOIN (consulte mi publicación ¿Existe una diferencia de ejecución entre una condición JOIN y una condición WHERE? )El código fuente de todo esto es
sql/sql_select.cc
Evidentemente, el
ORDER BY
árbol va a mantener la evaluación deFIELD(id,3,2,1,4)
. Por lo tanto, los números 0,1,2,3,4 son los valores que se ordenan mientras llevan una referencia a la fila involucrada.fuente
N
valores en ambosIN
yFIELD
. En este ejemploN=4
. ¿Entiendo correctamente que esta consulta va a realizar al menos~N^2
operaciones? Porque cadaFIELD
cálculo hace~N
comparaciones una vez para cada fila. Si es así, esto es bastante lento para grandes ¿N
Tal vez no es un enfoque muy bueno?FIELD()
función debería ser unaO(1)
operación porqueFIELD()
tiene un índice numéricoid
. Por lo tanto, no veo nada más peroO(n)
basado en filas. No veoFIELD()
hacer ninguna operación iterativa como la queGREATEST()
tendría que hacer.FIELD
tieneN
argumentos para comparar, ejecutaráN
comparaciones. ¿De qué otra manera va a comparar un número conN
otros números si no lo haceO(N)
? La única posibilidad que se me ocurre es algún tipo de optimización a través de una estructura de datos especial como un hash o un árbol de argumentos. En realidad, sé queIN
sí tiene tal optimización. No lo seFIELD
. ¿Qué quiere decir con un "índice numérico"?Tal vez esto esté demasiado lejos del código real, por lo que no tiene un nivel lo suficientemente bajo como lo que quería:
Cuando MySQL no puede usar el índice para recuperar datos en orden, crea una tabla / conjunto de resultados temporal con todas las columnas seleccionadas y algunos datos adicionales, uno de ellos es una especie de columna para almacenar los resultados del valor de expresión ORDER BY para cada fila. luego envía esta tabla tmp a una rutina "clasificador de archivos" con información por qué columna ordenar. Después de eso, las filas están ordenadas para que pueda elegirlas una por una y devolver las columnas seleccionadas.
fuente
FIELD
funcionan los cálculos. Me temo que puede tener un impacto significativo en el rendimiento.