Límite de memoria superado para la consulta
Agregaciones
max_bytes_before_external_group_by
y max_bytes_before_external_sort, respectivamente.
El primero de ellos se analiza en detalle aquí.
En resumen, esto garantiza que cualquier agregación pueda volcarse a disco si se supera un
umbral de memoria. Esto inevitablemente afectará al rendimiento de la consulta, pero
ayudará a garantizar que las consultas no provoquen OOM. El segundo ajuste de ordenación ayuda a resolver problemas similares
con ordenaciones que consumen mucha memoria. Esto puede ser especialmente importante en
entornos distribuidos donde un nodo coordinador recibe respuestas ordenadas
de segmentos secundarios. En este caso, se puede pedir al
servidor coordinador que ordene un
conjunto de datos más grande que la memoria disponible. Con max_bytes_before_external_sort,
se puede permitir que la ordenación se vuelque a disco. Esta configuración también es útil en
casos en los que el usuario tiene un ORDER BY después de un GROUP BY con un LIMIT,
especialmente cuando la consulta es distribuida.
Joins
JOIN, lo que puede ayudar a
reducir la memoria necesaria. De forma predeterminada, los joins usan hash join, que suele ofrecer
la mayor cobertura de funcionalidades y, a menudo, el mejor rendimiento.
Este algoritmo carga la tabla del lado derecho del JOIN en una tabla hash en memoria,
sobre la que luego se evalúa la tabla del lado izquierdo. Para minimizar el uso de memoria,
los usuarios deben, por tanto, colocar la tabla más pequeña en el lado derecho. Sin embargo, este enfoque
sigue teniendo limitaciones en escenarios con restricciones de memoria. En esos casos, se puede
habilitar el join partial_merge mediante la configuración join_algorithm.
Esta variante del algoritmo sort-merge
primero ordena la tabla derecha en bloques y crea un índice min-max para ellos.
Luego ordena partes de la tabla izquierda por la clave del join y las combina con la
tabla derecha. El índice min-max se utiliza para omitir bloques innecesarios de la tabla derecha.
Este método consume menos memoria, a costa del rendimiento. Llevando este concepto
un paso más allá, el algoritmo full_sorting_merge permite realizar un JOIN cuando
el lado derecho es muy grande y no cabe en memoria y las operaciones de lookup son
imposibles, por ejemplo, en una subconsulta compleja. En este caso, tanto el lado derecho como el izquierdo
se ordenan en disco si no caben en memoria, lo que permite unir tablas grandes.
Desde la versión 20.3, ClickHouse admite un valor auto para la configuración join_algorithm.
Esto indica a ClickHouse que aplique un enfoque adaptativo de join, en el que se prioriza el algoritmo
hash join hasta que se superan los límites de memoria, momento en el que se
intenta el algoritmo partial_merge. Por último, en lo que respecta a los joins, animamos
a los lectores a familiarizarse con el comportamiento de los distributed joins y con cómo minimizar
su consumo de memoria. Puede encontrarse más información aquí.