ORDER BY contiene:
- una lista de expresiones, por ejemplo,
ORDER BY visits, search_phrase; - una lista de números que hacen referencia a las columnas de la cláusula
SELECT, por ejemplo,ORDER BY 2, 1; o ALL, que significa todas las columnas de la cláusulaSELECT, por ejemplo,ORDER BY ALL.
ALL, establezca el ajuste enable_order_by_all = 0.
La cláusula ORDER BY puede incluir un modificador DESC (descendente) o ASC (ascendente), que determina la dirección de ordenación.
A menos que se especifique explícitamente un criterio de ordenación, se usa ASC de forma predeterminada.
La dirección de ordenación se aplica a una sola expresión, no a toda la lista; por ejemplo, ORDER BY Visits DESC, SearchPhrase.
Además, la ordenación distingue entre mayúsculas y minúsculas.
Las filas con valores idénticos en las expresiones de ordenación se devuelven en un orden arbitrario y no determinista.
Si se omite la cláusula ORDER BY en una sentencia SELECT, el orden de las filas también es arbitrario y no determinista.
Ordenación de valores especiales
Hay dos opciones para el orden de ordenación deNaN y NULL:
- De forma predeterminada o con el modificador
NULLS LAST: primero los valores, luegoNaNy despuésNULL. - Con el modificador
NULLS FIRST: primeroNULL, luegoNaNy después los demás valores.
Ejemplo
Para la tablaSELECT * FROM t_null_nan ORDER BY y NULLS FIRST para obtener lo siguiente:
Compatibilidad con la intercalación
Para ordenar valores String, puede especificar una intercalación (comparación). Ejemplo:ORDER BY SearchPhrase COLLATE 'tr': para ordenar por palabra clave en orden ascendente, usando el alfabeto turco, sin distinguir entre mayúsculas y minúsculas, asumiendo que las cadenas están codificadas en UTF-8. COLLATE puede especificarse, o no, de forma independiente para cada expresión en ORDER BY. Si se especifica ASC o DESC, COLLATE se coloca después. Al usar COLLATE, la ordenación siempre distingue entre mayúsculas y minúsculas.
La intercalación es compatible con LowCardinality, Nullable, Array y Tuple.
Solo recomendamos usar COLLATE para la ordenación final de un número reducido de filas, ya que ordenar con COLLATE es menos eficiente que la ordenación normal por bytes.
Ejemplos de intercalación
Ejemplo solo con valores String: Tabla de entrada:Query
Response
Query
Response
Query
Response
Query
Response
Response
Query
Response
Detalles de implementación
Se utiliza menos RAM si, además deORDER BY, se especifica un LIMIT lo bastante pequeño. De lo contrario, la cantidad de memoria utilizada es proporcional al volumen de datos que se va a ordenar. Un rango LIMIT ... AFTER ... UNTIL no la reduce, porque no se conoce el tamaño del rango hasta que los datos se han ordenado. En el procesamiento distribuido de consultas, si se omite GROUP BY, la ordenación se realiza parcialmente en los servidores remotos y los resultados se fusionan en el servidor que realiza la solicitud. Esto significa que, en la ordenación distribuida, el volumen de datos que se debe ordenar puede ser mayor que la cantidad de memoria disponible en un solo servidor.
Si no hay suficiente RAM, es posible realizar la ordenación en memoria externa (creando archivos temporales en disco). Para ello, use el SETTING max_bytes_before_external_sort. Si se establece en 0 (el valor predeterminado), la ordenación externa se desactiva. Si está habilitada, cuando el volumen de datos que se debe ordenar alcanza la cantidad de bytes especificada, los datos recopilados se ordenan y se vuelcan en un archivo temporal. Después de leer todos los datos, todos los archivos ordenados se fusionan y se generan los resultados. Los archivos se escriben en el directorio /var/lib/clickhouse/tmp/ configurado (de forma predeterminada, aunque puede usar el parámetro tmp_path para cambiar este SETTING). También puede usar spilling to disk solo si la consulta supera los límites de memoria; es decir, max_bytes_ratio_before_external_sort=0.6 habilitará el spilling to disk solo cuando la consulta alcance el 60% del límite de memoria (usuario/servidor).
La ejecución de una consulta puede usar más memoria que max_bytes_before_external_sort. Por este motivo, este SETTING debe tener un valor significativamente menor que max_memory_usage. Por ejemplo, si su servidor tiene 128 GB de RAM y necesita ejecutar una sola consulta, establezca max_memory_usage en 100 GB y max_bytes_before_external_sort en 80 GB.
La ordenación externa es mucho menos eficaz que la ordenación en RAM.
Optimización de la lectura de datos
Si la expresiónORDER BY tiene un prefijo que coincide con la clave de ordenación de la tabla, puede optimizar la consulta mediante la SETTING optimize_read_in_order.
Cuando la SETTING optimize_read_in_order está habilitada, el servidor de ClickHouse usa el índice de la tabla y lee los datos en el orden de la clave ORDER BY. Esto permite evitar leer todos los datos cuando se especifica LIMIT. Lo mismo ocurre con un rango LIMIT ... AFTER ... UNTIL sin ALL, que detiene la lectura una vez que su rango ha terminado. Por tanto, las consultas sobre grandes volúmenes de datos con un límite pequeño se procesan más rápido.
La optimización funciona tanto con ASC como con DESC, y no funciona junto con la cláusula GROUP BY. Con el modificador FINAL, la optimización funciona en el orden directo de la clave de ordenación y, en el caso de las tablas ReplacingMergeTree, también en el orden inverso, controlado por la SETTING optimize_read_in_reverse_order_final.
Cuando la SETTING optimize_read_in_order está deshabilitada, el servidor de ClickHouse no usa el índice de la tabla al procesar consultas SELECT.
Considere deshabilitar manualmente optimize_read_in_order al ejecutar consultas que tengan una cláusula ORDER BY, un LIMIT grande y una condición WHERE que requiera leer una gran cantidad de registros antes de encontrar los datos consultados.
La optimización es compatible con los siguientes motores de tabla:
- MergeTree (incluidas las vistas materializadas),
- Merge,
- Buffer
MaterializedView, la optimización funciona con vistas como SELECT ... FROM merge_tree_table ORDER BY pk. Pero no es compatible con consultas como SELECT ... FROM view ORDER BY pk si la consulta de la vista no incluye la cláusula ORDER BY.
Modificador ORDER BY Expr WITH FILL
Este modificador también se puede combinar con el modificador LIMIT … WITH TIES y con la forma de rango LIMIT … AFTER … UNTIL. El modificadorWITH FILL puede especificarse después de ORDER BY expr, con los parámetros opcionales FROM expr, TO expr y STEP expr.
Todos los valores ausentes de la columna expr se rellenarán secuencialmente y las demás columnas se rellenarán con sus valores predeterminados.
Para rellenar varias columnas, agregue el modificador WITH FILL, con parámetros opcionales, después de cada nombre de campo en la sección ORDER BY.
Query
WITH FILL se puede aplicar a campos con tipos numéricos (cualquier tipo de float, decimal o int) o tipos Date/DateTime. Cuando se aplica a campos String, los valores que faltan se rellenan con cadenas vacías.
Cuando no se define FROM const_expr, la secuencia de relleno usa el valor mínimo del campo expr de ORDER BY.
Cuando no se define TO const_expr, la secuencia de relleno usa el valor máximo del campo expr de ORDER BY.
Cuando se define STEP const_numeric_expr, const_numeric_expr se interpreta as is para los tipos numéricos, como days para el tipo Date y como seconds para el tipo DateTime. También admite el tipo de dato INTERVAL, que representa intervalos de fecha y hora.
Cuando se omite STEP const_numeric_expr, la secuencia de relleno usa 1.0 para el tipo numérico, 1 day para el tipo Date y 1 second para el tipo DateTime.
Cuando se define STALENESS const_numeric_expr, la consulta generará filas hasta que la diferencia con la fila anterior en los datos originales supere const_numeric_expr.
INTERPOLATE se puede aplicar a columnas que no participan en ORDER BY WITH FILL. Estas columnas se rellenan en función de los valores de los campos anteriores al aplicar expr. Si expr no está presente, se repetirá el valor anterior. Si se omite la lista, se incluirán todas las columnas permitidas.
Ejemplo de una consulta sin WITH FILL:
Query
Response
WITH FILL:
Query
Response
ORDER BY field2 WITH FILL, field1 WITH FILL, el orden de relleno seguirá el orden de los campos en la cláusula ORDER BY.
Ejemplo:
Query
Response
d1 no se rellena ni usa el valor predeterminado porque no tenemos valores repetidos del valor d2, y la secuencia de d1 no puede calcularse correctamente.
La siguiente consulta con el campo cambiado en ORDER BY:
Query
Response
INTERVAL de 1 día para cada valor rellenado en la columna d1:
Query
Response
STALENESS:
Query
Response
STALENESS 3:
Query
Response
INTERPOLATE:
Query
Response
INTERPOLATE:
Query
Response
Relleno agrupado por prefijo de ordenación
Puede ser útil rellenar de forma independiente las filas que tienen los mismos valores en determinadas columnas; un buen ejemplo es rellenar los valores que faltan en series temporales. Supongamos que existe la siguiente tabla de series temporales:sensor_id como prefijo de ordenación para rellenar la columna timestamp:
value se interpoló con 9999 solo para que las filas rellenadas se distingan más fácilmente.
Este comportamiento se controla mediante la configuración use_with_fill_by_sorting_prefix (habilitada de forma predeterminada)