¿Qué son las particiones de tabla en ClickHouse?
Las particiones agrupan las partes de datos de una tabla de la familia de motores MergeTree en unidades lógicas y organizadas: una forma de organizar los datos con sentido conceptual y alineada con criterios específicos, como rangos de tiempo, categorías u otros atributos clave. Estas unidades lógicas facilitan la gestión, consulta y optimización de los datos.
PARTITION BY
PARTITION BY toStartOfMonth(date), que organiza las partes de datos de la tabla según el mes de venta de las propiedades:
Estructura en disco
El servidor de ClickHouse primero divide las filas del ejemplo de inserción, con 4 filas representadas en el diagrama anterior, según el valor de su clave de partición
toStartOfMonth(date).
Luego, para cada partición identificada, las filas se procesan como es habitual mediante varios pasos secuenciales (① Ordenación, ② División en columnas, ③ Compresión, ④ Escritura en disco).
Ten en cuenta que, con el particionamiento habilitado, ClickHouse crea automáticamente índices MinMax para cada parte de datos. Se trata simplemente de archivos para cada columna de la tabla utilizada en la expresión de la clave de partición, que contienen los valores mínimo y máximo de esa columna dentro de la parte de datos.
Fusiones por partición
Como se muestra en el diagrama anterior, las partes que pertenecen a particiones distintas nunca se fusionan. Si se elige una clave de partición con alta cardinalidad, las partes distribuidas entre miles de particiones nunca serán candidatas a fusión, lo que hará que se superen los límites preconfigurados y provocará el temido error
Too many parts. Resolver este problema es sencillo: elija una clave de partición razonable con una cardinalidad inferior a 1000..10000.
Monitorización de particiones
_partition_value:
Como alternativa, ClickHouse realiza un seguimiento de todas las partes y particiones de todas las tablas en la tabla del sistema system.parts, y la siguiente consulta devuelve, para nuestra tabla de ejemplo, la lista de todas las particiones, junto con el número actual de partes activas y la suma de filas de esas partes por partición:
¿Para qué se usan las particiones de tabla?
Gestión de datos
toStartOfMonth(date), se eliminarán particiones completas (conjuntos de partes de tabla) que cumplan la condición de TTL, lo que hace que la operación de limpieza sea más eficiente, sin necesidad de reescribir partes.
Del mismo modo, en lugar de eliminar los datos antiguos, estos pueden trasladarse de forma automática y eficiente a un nivel de almacenamiento más rentable:
Optimización de consultas
date) usada en la clave de partición de la tabla como por una columna (town) usada en la clave primaria de la tabla (y date no forma parte de la clave primaria).
ClickHouse procesa esa consulta aplicando una secuencia de técnicas de poda para evitar evaluar datos irrelevantes:
① Poda de particiones: se usan los índices MinMax para ignorar particiones completas (conjuntos de partes) que, lógicamente, no pueden coincidir con el filtro de la consulta sobre columnas usadas en la clave de partición de la tabla. ② Poda de gránulos: para las partes de datos restantes tras el paso ①, se usa su índice primario para ignorar todos los gránulos (bloques de filas) que, lógicamente, no pueden coincidir con el filtro de la consulta sobre columnas usadas en la clave primaria de la tabla. Podemos observar estos pasos de poda de datos inspeccionando el plan físico de ejecución de la consulta para la consulta de ejemplo anterior mediante una cláusula EXPLAIN:
date para identificar 11 de los 3257 gránulos existentes (bloques de filas) almacenados en 1 de las 436 partes de datos activas existentes que contienen filas que coinciden con el filtro date de la consulta.
② Poda de gránulos: Las filas 19 a 24 de la salida de EXPLAIN anterior indican que ClickHouse luego usa el índice primario (creado sobre el campo town) de la parte de datos identificada en el paso ① para reducir aún más el número de gránulos (que contienen filas que potencialmente también coinciden con el filtro town de la consulta) de 11 a 1. Esto también se refleja en la salida del cliente de ClickHouse que imprimimos más arriba para la ejecución de la consulta:
El particionamiento es principalmente una función de gestión de datos
uk_price_paid_simple_partitioned tiene más de 600 particiones y, por lo tanto, 600 306 partes de datos activas. En cambio, en nuestra tabla no particionada uk_price_paid_simple, todas las partes de datos iniciales pudieron fusionarse en una sola parte activa mediante fusiones en segundo plano.
Cuando comprobamos el plan físico de ejecución de la consulta con una cláusula EXPLAIN para nuestra consulta de ejemplo anterior, sin el filtro de partición, ejecutada sobre la tabla particionada, podemos ver en las filas 19 y 20 de la salida siguiente que ClickHouse identificó 671 de los 3257 gránulos existentes (bloques de filas), repartidos en 431 de las 436 partes de datos activas existentes, que potencialmente contienen filas que coinciden con el filtro de la consulta y que, por lo tanto, serán examinados y procesados por el motor de consultas: