Skip to main content

Descripción

El motor CollapsingMergeTree hereda de MergeTree y añade lógica para colapsar filas durante el proceso de fusión. El motor de tabla CollapsingMergeTree elimina (colapsa) de forma asíncrona pares de filas si todos los campos de la clave de ordenación (ORDER BY) son equivalentes, excepto el campo especial Sign, que puede tener los valores 1 o -1. Las filas que no tienen una pareja con el valor opuesto de Sign se conservan. Para obtener más información, consulte la sección colapsado de este documento.
Este motor puede reducir significativamente el volumen de almacenamiento, lo que, en consecuencia, aumenta la eficiencia de las consultas SELECT.

Parámetros

Todos los parámetros de este motor de tabla, salvo el parámetro Sign, tienen el mismo significado que en MergeTree.
  • Sign — El nombre de una columna con el tipo de fila, donde 1 es una fila de estado y -1 es una fila de cancelación. Tipo: Int8.

Crear una tabla

colapsado

Datos

Considera la situación en la que necesitas guardar datos que cambian continuamente para un objeto determinado. Puede parecer lógico tener una fila por objeto y actualizarla cada vez que cambie algo; sin embargo, las operaciones de actualización son costosas y lentas para el DBMS porque requieren reescribir los datos en el almacenamiento. Si necesitamos escribir datos rápidamente, realizar un gran número de actualizaciones no es un enfoque aceptable, pero siempre podemos escribir los cambios de un objeto de forma secuencial. Para ello, utilizamos la columna especial Sign.
  • Si Sign = 1, significa que la fila es una fila de “estado”: una fila que contiene campos que representan un estado válido actual.
  • Si Sign = -1, significa que la fila es una fila de “cancelación”: una fila utilizada para cancelar el estado de un objeto con los mismos atributos.
Por ejemplo, queremos calcular cuántas páginas visitaron los usuarios en un sitio web y durante cuánto tiempo. En un momento dado, escribimos la siguiente fila con el estado de la actividad del usuario:
Más adelante, registramos el cambio en la actividad del usuario y lo escribimos con las dos filas siguientes:
La primera fila cancela el estado anterior del objeto (que en este caso representa a un usuario). Debe copiar todos los campos de la clave de ordenación de la fila “cancelada”, excepto Sign. La segunda fila anterior contiene el estado actual. Como solo necesitamos el último estado de la actividad del usuario, la fila original de “estado” y la fila de “cancelación” que insertamos pueden eliminarse, como se muestra a continuación, colapsando el estado no válido (antiguo) de un objeto:
CollapsingMergeTree lleva a cabo precisamente este comportamiento de collapsing durante la fusión de las partes de datos.
La razón por la que se necesitan dos filas para cada cambio se explica con más detalle en el apartado Algoritmo.
Las particularidades de este enfoque
  1. El programa que escribe los datos debe recordar el estado de un objeto para poder cancelarlo. La fila de “cancelación” debe contener copias de los campos de la clave de ordenación del “estado” y el Sign opuesto. Esto aumenta el tamaño inicial del almacenamiento, pero permite escribir los datos rápidamente.
  2. Los arrays largos y en crecimiento en las columnas reducen la eficiencia del engine debido al aumento de la carga de escritura. Cuanto más sencillos sean los datos, mayor será la eficiencia.
  3. Los resultados de SELECT dependen en gran medida de la consistencia del historial de cambios del objeto. Sea preciso al preparar los datos para insertarlos. Los datos inconsistentes pueden producir resultados impredecibles. Por ejemplo, valores negativos para métricas no negativas, como la profundidad de la sesión.

Algoritmo

Cuando ClickHouse fusiona partes de datos, cada grupo de filas consecutivas con la misma clave de ordenación (ORDER BY) se reduce a no más de dos filas: la fila de estado con Sign = 1 y la fila de cancelación con Sign = -1. En otras palabras, en ClickHouse las entradas se colapsan. Para cada parte de datos resultante, ClickHouse guarda: Además, cuando hay al menos dos filas de estado más que filas de cancelación o al menos dos filas de cancelación más que filas de estado, la fusión continúa. Sin embargo, ClickHouse considera esta situación un error lógico y lo registra en el registro del servidor. Este error puede producirse si los mismos datos se insertan más de una vez. Por lo tanto, el colapsado no debería cambiar los resultados del cálculo de estadísticas. Los cambios se colapsan gradualmente, de modo que al final solo queda el último estado de casi todos los objetos. La columna Sign es necesaria porque el algoritmo de fusión no garantiza que todas las filas con la misma clave de ordenación estén en la misma parte de datos resultante ni siquiera en el mismo servidor físico. ClickHouse procesa las consultas SELECT con múltiples hilos y no puede predecir el orden de las filas en el resultado. La agregación es necesaria si se necesita obtener datos completamente “colapsados” de la tabla CollapsingMergeTree. Para completar el colapsado, escriba una consulta con la cláusula GROUP BY y funciones de agregación que tengan en cuenta el signo. Por ejemplo, para calcular la cantidad, use sum(Sign) en lugar de count(). Para calcular la suma de algo, use sum(Sign * x) junto con HAVING sum(Sign) > 0 en lugar de sum(x), como en el ejemplo a continuación. Las funciones de agregación count, sum y avg pueden calcularse de esta forma. La función de agregación uniq puede calcularse si un objeto tiene al menos un estado no colapsado. Las funciones de agregación min y max no pueden calcularse porque CollapsingMergeTree no conserva el historial de los estados colapsados.
Si necesita extraer datos sin agregación (por ejemplo, para comprobar si existen filas cuyos valores más recientes coinciden con ciertas condiciones), puede usar el modificador FINAL para la cláusula FROM. Este fusionará los datos antes de devolver el resultado. Para CollapsingMergeTree, solo se devuelve la fila de estado más reciente para cada clave.

Ejemplos

Ejemplo de uso

Con los siguientes datos de ejemplo:
Vamos a crear una tabla UAct con CollapsingMergeTree:
A continuación, insertaremos algunos datos:
Usamos dos consultas INSERT para crear dos partes de datos diferentes.
Si insertamos los datos con una sola consulta, ClickHouse crea solo una parte de datos y no realizará ninguna fusión.
Podemos seleccionar los datos con:
Veamos los datos devueltos arriba y comprobemos si se produjo el collapsing… Con dos consultas INSERT, creamos dos partes de datos. La consulta SELECT se ejecutó en dos hilos y obtuvimos un orden aleatorio de las filas. Sin embargo, el collapsing no se produjo porque todavía no se había realizado ninguna fusión de las partes de datos, y ClickHouse fusiona las partes de datos en segundo plano en un momento desconocido que no podemos predecir. Por lo tanto, necesitamos una agregación, que realizamos con la función de agregación sum y la cláusula HAVING:
Si no necesitamos agregación y queremos forzar el colapsado, también podemos usar el modificador FINAL en la cláusula FROM.
Esta forma de seleccionar los datos es menos eficiente y no se recomienda para grandes volúmenes de datos analizados (millones de filas).

Ejemplo de otro enfoque

La idea de este enfoque es que las fusiones solo tienen en cuenta los campos clave. Por tanto, en la fila de “cancelación”, podemos especificar valores negativos que compensen la versión anterior de la fila al sumar, sin usar la columna Sign. Para este ejemplo, utilizaremos los datos de muestra que aparecen a continuación:
Para este enfoque, es necesario cambiar los tipos de datos de PageViews y Duration para poder almacenar valores negativos. Por lo tanto, cambiamos el tipo de estas columnas de UInt8 a Int16 cuando creamos nuestra tabla UAct con collapsingMergeTree:
Probemos este enfoque insertando datos en nuestra tabla. Sin embargo, en ejemplos o tablas pequeñas, es aceptable:
Última modificación el 23 de julio de 2026