Esta es la Parte 3 de una guía sobre cómo migrar de PostgreSQL a ClickHouse. Mediante un ejemplo práctico, muestra cómo modelar datos en ClickHouse al migrar desde PostgreSQL.Recomendamos a los usuarios que migran desde Postgres que lean la guía para modelar datos en ClickHouse. Esta guía utiliza el mismo conjunto de datos de Stack Overflow y explora varios enfoques con las funcionalidades de ClickHouse.
Los usuarios que provienen de bases de datos OLTP suelen buscar el concepto equivalente en ClickHouse. Al ver que ClickHouse admite la sintaxis
PRIMARY KEY, podrían sentirse tentados a definir el esquema de su tabla con las mismas claves que en su base de datos OLTP de origen. Esto no es apropiado.
¿En qué se diferencian las claves primarias de ClickHouse?
- Las claves primarias de Postgres son, por definición, únicas por fila. El uso de estructuras B-tree permite buscar filas individuales de forma eficiente mediante esta clave. Aunque ClickHouse puede optimizarse para buscar el valor de una única fila, las cargas de trabajo analíticas suelen requerir leer unas pocas columnas, pero de muchas filas. Con más frecuencia, los filtros deberán identificar un subconjunto de filas sobre el que se realizará una agregación.
- La eficiencia en memoria y disco es fundamental a la escala a la que suele utilizarse ClickHouse. Los datos se escriben en las tablas de ClickHouse en fragmentos conocidos como partes, y se aplican reglas para fusionar esas partes en segundo plano. En ClickHouse, cada parte tiene su propio índice primario. Cuando las partes se fusionan, los índices primarios de la parte resultante también se fusionan. A diferencia de Postgres, estos índices no se construyen para cada fila. En su lugar, el índice primario de una parte tiene una entrada de índice por cada grupo de filas; esta técnica se denomina indexación dispersa.
- La indexación dispersa es posible porque ClickHouse almacena en disco las filas de una parte ordenadas por una clave especificada. En lugar de localizar directamente filas individuales (como hace un índice basado en B-tree), el índice primario disperso le permite identificar rápidamente (mediante una búsqueda binaria sobre las entradas del índice) grupos de filas que podrían coincidir con la consulta. Los grupos de filas potencialmente coincidentes identificados se envían después, en paralelo, al motor de ClickHouse para encontrar las coincidencias. Este diseño de índice permite que el índice primario sea pequeño (cabe por completo en la memoria principal) y, aun así, acelere significativamente los tiempos de ejecución de las consultas, especialmente en las consultas por rango típicas de los casos de uso de análisis de datos.
Todas las columnas de una tabla se ordenarán según el valor de la clave de ordenación especificada, independientemente de si están incluidas o no en la propia clave. Por ejemplo, siCreationDatese usa como clave, el orden de los valores de todas las demás columnas corresponderá al orden de los valores de la columnaCreationDate. Se pueden especificar varias claves de ordenación; en ese caso, el orden seguirá la misma semántica que una cláusulaORDER BYen una consultaSELECT.
Elección de una clave de ordenación
Particiones
PARTITION BY. Esta cláusula puede contener una expresión SQL sobre cualquier columna, cuyo resultado definirá a qué partición se envía una fila.
Las partes de datos se asocian lógicamente con cada partición en disco y pueden consultarse de forma aislada. En el ejemplo siguiente, particionamos la tabla posts por año usando la expresión toYear(CreationDate). A medida que se insertan filas en ClickHouse, esta expresión se evaluará para cada fila y se enviará a la partición correspondiente si existe (si la fila es la primera de un año, se creará la partición).
Aplicaciones de las particiones
- Gestión de datos - En ClickHouse, debes considerar el particionamiento principalmente como una funcionalidad de gestión de datos, no como una técnica de optimización de consultas. Al separar los datos de forma lógica según una clave, cada partición puede gestionarse de manera independiente; por ejemplo, puede eliminarse. Esto permite mover particiones y, por tanto, subconjuntos de datos, entre niveles de almacenamiento de forma eficiente en función del tiempo o hacer que los datos expiren/eliminarlos de forma eficiente del clúster. En el ejemplo siguiente, eliminamos publicaciones de 2008.
- Optimización de consultas - Aunque el particionamiento puede ayudar a mejorar el rendimiento de las consultas, esto depende en gran medida de los patrones de acceso. Si las consultas se limitan a unas pocas particiones (idealmente una sola), el rendimiento puede mejorar. Normalmente, esto solo resulta útil si la clave de particionamiento no está en la clave primaria y se filtra por ella. Sin embargo, las consultas que necesitan abarcar muchas particiones pueden tener peor rendimiento que si no se usara particionamiento (ya que este puede dar lugar a más partes). La ventaja de dirigirse a una sola partición será aún menor, o incluso inexistente, si la clave de particionamiento ya aparece entre las primeras columnas de la clave primaria. El particionamiento también puede usarse para optimizar las consultas GROUP BY si los valores de cada partición son únicos. Sin embargo, en general, debes asegurarte de que la clave primaria esté optimizada y considerar el particionamiento como una técnica de optimización de consultas solo en casos excepcionales, cuando los patrones de acceso se centran en un subconjunto específico y predecible del tiempo; por ejemplo, particionar por día cuando la mayoría de las consultas se realizan sobre el último día.
Recomendaciones para las particiones
Internamente, ClickHouse crea partes para los datos insertados. A medida que se insertan más datos, aumenta el número de partes. Para evitar un número excesivo de partes, que degradará el rendimiento de las consultas (al haber más archivos que leer), las partes se fusionan en un proceso asíncrono en segundo plano. Si el número de partes supera un límite preconfigurado, ClickHouse lanzará una excepción durante la inserción con un error de “demasiadas partes”. Esto no debería ocurrir en condiciones normales de funcionamiento y solo sucede si ClickHouse está mal configurado o se usa de forma incorrecta; por ejemplo, con muchas inserciones pequeñas.
Como las partes se crean de forma aislada para cada partición, aumentar el número de particiones hace que también aumente el número de partes; es decir, es un múltiplo del número de particiones. Por lo tanto, las claves de partición de alta cardinalidad pueden provocar este error y deben evitarse.
Vistas materializadas vs proyecciones
ORDER BY para una tabla.
En la documentación de modelado de datos de ClickHouse, exploramos cómo pueden usarse las vistas materializadas en ClickHouse para precomputar agregaciones, transformar filas y optimizar consultas para distintos patrones de acceso.
Para este último caso, mostramos un ejemplo en el que la vista materializada envía filas a una tabla de destino con un orden de clasificación distinto al de la tabla original que recibe las inserciones.
Por ejemplo, considere la siguiente consulta:
UserId no es la clave de ordenación.
Anteriormente, resolvimos esto usando una vista materializada que actuaba como tabla de búsqueda para PostId. El mismo problema puede resolverse
con una proyección. El siguiente comando añade una
proyección para ORDER BY user_id.
ALTER, su creación es asíncrona cuando se ejecuta el comando MATERIALIZE PROJECTION. Puede comprobar el progreso de esta operación con la siguiente consulta y esperar a que is_done=1.
EXPLAIN, también confirmamos que se utilizó la proyección para ejecutar esta consulta:
Cuándo usar proyecciones
- Se requiere una reordenación completa de los datos. Aunque la expresión de la
proyección puede, en teoría, usar un
GROUP BY,las vistas materializadas son más eficaces para mantener agregados. También es más probable que el optimizador de consultas aproveche las proyecciones que usan una reordenación simple, es decir,SELECT * ORDER BY x. Puede seleccionar un subconjunto de columnas en esta expresión para reducir la huella de almacenamiento. - Los usuarios aceptan el aumento asociado de la huella de almacenamiento y la sobrecarga de escribir los datos dos veces. Pruebe el impacto en la velocidad de inserción y evalúe la sobrecarga de almacenamiento.
Desde la versión 25.5, ClickHouse admite la columna virtual
_part_offset en las
proyecciones. Esto ofrece una forma de almacenar proyecciones más eficiente en cuanto a espacio.Para más detalles, consulte “Projections”