El particionamiento está disponible para las tablas de la familia MergeTree, incluidas las tablas replicadas y las vistas materializadas.
Una partición es una agrupación lógica de registros de una tabla según un criterio determinado. Puede definir una partición con cualquier criterio, por ejemplo, por mes, por día o por tipo de evento. Cada partición se almacena por separado para simplizar la manipulación de estos datos. Al acceder a los datos, ClickHouse utiliza el subconjunto más pequeño posible de particiones. Las particiones mejoran el rendimiento de las consultas que incluyen una clave de partición porque ClickHouse filtrará por esa partición antes de seleccionar las partes y los gránulos dentro de ella.
La partición se especifica en la cláusula PARTITION BY expr al crear una tabla. La clave de partición puede ser cualquier expresión basada en las columnas de la tabla. Por ejemplo, para especificar el particionamiento por mes, use la expresión toYYYYMM(date_column):
CREATE TABLE visits
(
VisitDate Date,
Hour UInt8,
ClientID UUID
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(VisitDate)
ORDER BY Hour;La clave de partición también puede ser una tupla de expresiones (igual que la clave primaria). Por ejemplo:
ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/name', 'replica1', Sign)
PARTITION BY (toMonday(StartDate), EventType)
ORDER BY (CounterID, StartDate, intHash32(UserID));En este ejemplo, configuramos el particionamiento por los tipos de eventos que se produjeron durante la semana actual.
De forma predeterminada, no se admite la clave de partición de coma flotante. Para usarla, habilite la opción allow_floating_point_partition_key.
Al insertar datos nuevos en una tabla, estos se almacenan como una parte independiente (fragmento), ordenada por la clave primaria. Entre 10 y 15 minutos después de la inserción, las partes de la misma partición se fusionan en una sola parte.
Use la tabla system.parts para ver las partes de la tabla y las particiones. Por ejemplo, supongamos que tenemos una tabla visits con particionamiento por mes. Realicemos la consulta SELECT sobre la tabla system.parts:
SELECT
partition,
name,
active
FROM system.parts
WHERE table = 'visits'┌─partition─┬─name──────────────┬─active─┐
│ 201901 │ 201901_1_3_1 │ 0 │
│ 201901 │ 201901_1_9_2_11 │ 1 │
│ 201901 │ 201901_8_8_0 │ 0 │
│ 201901 │ 201901_9_9_0 │ 0 │
│ 201902 │ 201902_4_6_1_11 │ 1 │
│ 201902 │ 201902_10_10_0_11 │ 1 │
│ 201902 │ 201902_11_11_0_11 │ 1 │
└───────────┴───────────────────┴────────┘La columna partition contiene los nombres de las particiones. En este ejemplo hay dos particiones: 201901 y 201902. Puede usar el valor de esta columna para especificar el nombre de la partición en las consultas ALTER … PARTITION.
La columna name contiene los nombres de las partes de datos de la partición. Puede usar esta columna para especificar el nombre de la parte en la consulta ALTER ATTACH PART.
Desglosemos el nombre de la parte: 201901_1_9_2_11:
201901es el nombre de la partición.1es el número mínimo del bloque de datos.9es el número máximo del bloque de datos.2es el nivel del fragmento (la profundidad del árbol de fusiones del que se forma).11es la versión de la mutación (si la parte fue mutada)
La columna active muestra el estado de la parte. 1 está activa; 0, inactiva. Las partes inactivas son, por ejemplo, partes de origen que permanecen tras fusionarse en una parte más grande. Las partes de datos corruptas también se indican como inactivas.
Como puede ver en el ejemplo, hay varias partes separadas de la misma partición (por ejemplo, 201901_1_3_1 y 201901_1_9_2). Esto significa que esas partes aún no se han fusionado. ClickHouse fusiona periódicamente las partes de datos insertadas, aproximadamente 15 minutos después de la inserción. Además, puede realizar una fusión no programada mediante la consulta OPTIMIZE. Ejemplo:
OPTIMIZE TABLE visits PARTITION 201902;┌─partition─┬─name─────────────┬─active─┐
│ 201901 │ 201901_1_3_1 │ 0 │
│ 201901 │ 201901_1_9_2_11 │ 1 │
│ 201901 │ 201901_8_8_0 │ 0 │
│ 201901 │ 201901_9_9_0 │ 0 │
│ 201902 │ 201902_4_6_1 │ 0 │
│ 201902 │ 201902_4_11_2_11 │ 1 │
│ 201902 │ 201902_10_10_0 │ 0 │
│ 201902 │ 201902_11_11_0 │ 0 │
└───────────┴──────────────────┴────────┘Las partes inactivas se eliminarán aproximadamente 10 minutos después de la fusión.
Otra forma de ver el conjunto de partes y particiones es entrar en el directorio de la tabla: /var/lib/clickhouse/data/<database>/<table>/. Por ejemplo:
/var/lib/clickhouse/data/default/visits$ ls -l
total 40
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 1 16:48 201901_1_3_1
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201901_1_9_2_11
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 15:52 201901_8_8_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 15:52 201901_9_9_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201902_10_10_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201902_11_11_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:19 201902_4_11_2_11
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 12:09 201902_4_6_1
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 1 16:48 detachedLas carpetas '201901_1_1_0', '201901_1_7_1', etc. son los directorios de las partes. Cada parte corresponde a una partición y contiene datos solo de un mes determinado (la tabla de este ejemplo tiene particionamiento por mes).
El directorio detached contiene partes que se desvincularon de la tabla mediante la consulta DETACH. Las partes corruptas también se mueven a este directorio en lugar de eliminarse. El servidor no utiliza las partes del directorio detached. Puede añadir, eliminar o modificar los datos de este directorio en cualquier momento; el servidor no tendrá constancia de ello hasta que ejecute la consulta ATTACH.
Tenga en cuenta que, mientras el servidor está en funcionamiento, no puede cambiar manualmente el conjunto de partes ni sus datos en el sistema de archivos, ya que el servidor no tendrá constancia de ello. En las tablas no replicadas, puede hacerlo cuando el servidor está detenido, pero no se recomienda. En las tablas replicadas, el conjunto de partes no puede modificarse en ningún caso.
ClickHouse le permite realizar operaciones con las particiones: eliminarlas, copiarlas de una tabla a otra o crear una copia de seguridad. Consulte la lista de todas las operaciones en la sección Manipulación de particiones y partes.
Optimización de Group By mediante la clave de partición
Para algunas combinaciones de la clave de partición de la tabla y la clave de agrupación de la consulta, puede ser posible ejecutar la agregación de cada partición de forma independiente. Así, no tendremos que fusionar al final los datos parcialmente agregados de todos los hilos de ejecución, porque tenemos la garantía de que cada valor de la clave de agrupación no puede aparecer en los conjuntos de trabajo de dos hilos distintos.
El ejemplo típico es:
CREATE TABLE session_log
(
UserID UInt64,
SessionID UUID
)
ENGINE = MergeTree
PARTITION BY sipHash64(UserID) % 16
ORDER BY tuple();
SELECT
UserID,
COUNT()
FROM session_log
GROUP BY UserID;Los factores clave para obtener un buen rendimiento son:
- el número de particiones implicadas en la consulta debe ser suficientemente grande (más de
max_threads / 2); de lo contrario, la consulta no aprovechará completamente la máquina - las particiones no deben ser demasiado pequeñas, para evitar que el procesamiento por lotes se degrade a un procesamiento fila por fila
- las particiones deben tener tamaños comparables, para que todos los hilos realicen aproximadamente la misma cantidad de trabajo
Los ajustes relevantes son:
allow_aggregate_partitions_independently- controla si se habilita el uso de la optimizaciónforce_aggregate_partitions_independently- fuerza su uso cuando es aplicable desde el punto de vista de la corrección, pero la lógica interna que evalúa su conveniencia lo deshabilitamax_number_of_partitions_for_independent_aggregation- límite estricto del número máximo de particiones que puede tener la tabla