En esta página usamos indistintamente el término “clave de ordenación” para referirnos a la “clave primaria”. En sentido estricto, difieren en ClickHouse, pero, a efectos de este documento, pueden usarse como sinónimos, y la clave de ordenación hace referencia a las columnas especificadas en el ORDER BY de la tabla.
Tenga en cuenta que una clave primaria en ClickHouse funciona de forma muy diferente a lo que suele entenderse por este término en bases de datos OLTP como Postgres.
Elegir una clave primaria eficaz en ClickHouse es crucial para el rendimiento de las consultas y la eficiencia del almacenamiento. ClickHouse organiza los datos en partes, cada una con su propio índice primario disperso. Este índice acelera significativamente las consultas al reducir el volumen de datos escaneados. Además, como la clave primaria determina el orden físico de los datos en disco, afecta directamente a la eficiencia de compresión. Los datos ordenados de forma óptima se comprimen mejor, lo que a su vez mejora el rendimiento al reducir la E/S.
- Al seleccionar una clave de ordenación, priorice las columnas que se usan con frecuencia en los filtros de las consultas (es decir, en la cláusula
WHERE), especialmente aquellas que excluyen un gran número de filas. - Las columnas muy correlacionadas con otros datos de la tabla también son beneficiosas, ya que el almacenamiento contiguo mejora la tasa de compresión y la eficiencia de memoria durante las operaciones
GROUP BYyORDER BY.
Pueden aplicarse algunas reglas sencillas para ayudar a elegir una clave de ordenación. En ocasiones, los siguientes criterios pueden entrar en conflicto, así que considérelos en este orden. Este proceso puede ayudarle a identificar varias claves, aunque normalmente 4 o 5 suelen ser suficientes:
ImportanteLas claves de ordenación deben definirse al crear la tabla y no pueden añadirse después. Se puede agregar ordenación adicional a una tabla después (o antes) de la inserción de datos mediante una funcionalidad conocida como proyecciones. Tenga en cuenta que esto provoca duplicación de datos. Encontrará más detalles aquí.
Ejemplo
posts_unordered. Contiene una fila por cada publicación de Stack Overflow.
Esta tabla no tiene clave primaria, como indica ORDER BY tuple().
EXPLAIN indexes=1 confirma un escaneo completo de la tabla debido a la falta de índices.
posts_ordered, que contiene los mismos datos, se define con ORDER BY como (PostTypeId, toDate(CreationDate)), es decir:
PostTypeId tiene una cardinalidad de 8 y representa la opción lógica para el primer elemento de nuestra clave de ordenación. Dado que el filtrado con granularidad de fecha probablemente sea suficiente (aunque también seguirá beneficiando a los filtros de fecha y hora), usamos toDate(CreationDate) como segundo componente de nuestra clave. Esto también dará lugar a un índice más pequeño, ya que una fecha puede representarse con 16 bits, lo que acelera el filtrado.
La siguiente animación muestra cómo se crea un índice primario disperso optimizado para la tabla Posts de Stack Overflow. En lugar de indexar filas individuales, el índice se aplica a bloques de filas:
Si se repite la misma consulta en una tabla con esta clave de ordenación:
EXPLAIN indexes=1.
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 en la propia clave. Por ejemplo, si
CreationDate se usa como clave, el orden de los valores en todas las demás columnas se corresponderá con el orden de los valores de la columna CreationDate. Se pueden especificar varias claves de ordenación; esto ordenará con la misma semántica que una cláusula ORDER BY en una consulta SELECT.