- Mejorar el rendimiento de las consultas, especialmente cuando se usan con
JOINs - Enriquecer los datos ingeridos sobre la marcha sin ralentizar el proceso de ingestión
Acelerar los JOIN usando un Diccionario
JOIN: el tipo LEFT ANY, en el que la clave de join debe coincidir con el atributo clave del almacenamiento clave-valor subyacente.
Si este es el caso, ClickHouse puede aprovechar el diccionario para realizar un Direct Join. Este es el algoritmo de join más rápido de ClickHouse y puede aplicarse cuando el motor de tabla de la tabla del lado derecho admite solicitudes clave-valor de baja latencia. ClickHouse tiene tres motores de tabla que ofrecen esto: Join (que básicamente es una tabla hash precalculada), EmbeddedRocksDB y Diccionario. Describiremos el enfoque basado en diccionarios, pero el funcionamiento es el mismo para los tres motores.
El algoritmo de direct join requiere que la tabla derecha esté respaldada por un diccionario, de modo que los datos que se van a unir de esa tabla ya estén presentes en memoria en forma de una estructura de datos clave-valor de baja latencia.
Ejemplo
JOIN entre las tablas posts y votes:
Utilice conjuntos de datos más pequeños en el lado derecho deAunque esta consulta es rápida, requiere que escribamos elJOIN: Esta consulta puede parecer más verbosa de lo necesario, ya que el filtrado dePostIdse realiza tanto en la consulta externa como en la subconsulta. Se trata de una optimización de rendimiento que garantiza un tiempo de respuesta rápido de la consulta. Para obtener un rendimiento óptimo, asegúrese siempre de que el lado derecho deJOINsea el conjunto más pequeño posible. Para obtener consejos sobre cómo optimizar el rendimiento deJOINy comprender los algoritmos disponibles, recomendamos esta serie de artículos del blog.
JOIN con cuidado para lograr un buen rendimiento. Idealmente, simplemente filtraríamos las publicaciones para quedarnos con las que contienen “SQL” antes de examinar los recuentos de UpVote y DownVote del subconjunto de publicaciones para calcular nuestra métrica.
Aplicar un diccionario
votes:
En el ejemplo siguiente, los datos de nuestro diccionario provienen de una tabla de ClickHouse. Aunque esta es la fuente más común de los diccionarios, se admiten varias fuentes, incluidos archivos, HTTP y bases de datos como Postgres. Como mostraremos, los diccionarios pueden actualizarse automáticamente, lo que ofrece una forma ideal de garantizar que los conjuntos de datos pequeños sujetos a cambios frecuentes estén disponibles para direct joins.Nuestro diccionario requiere una clave primaria sobre la que se realizarán las búsquedas. Esto es conceptualmente idéntico a la clave primaria de una base de datos transaccional y debe ser única. Nuestra consulta anterior requiere una búsqueda sobre la clave de join:
PostId. A su vez, el diccionario debe poblarse con el total de votos positivos y negativos por PostId de nuestra tabla votes. Esta es la consulta para obtener los datos de este diccionario:
En OSS autogestionado, el comando anterior debe ejecutarse en todos los nodos. En ClickHouse Cloud, el Diccionario se replicará automáticamente en todos los nodos. Lo anterior se ejecutó en un nodo de ClickHouse Cloud con 64 GB de RAM y tardó 36 s en cargarse.Para confirmar la memoria que consume nuestro Diccionario:
PostId concreto con una simple función dictGet. A continuación, obtenemos los valores de la publicación 11227902:
Enriquecimiento en tiempo de consulta
Enriquecimiento durante la indexación
Location de un usuario en Stack Overflow nunca cambia (en realidad sí cambia), concretamente la columna Location de la tabla users. Supongamos que queremos hacer una consulta analítica sobre la tabla posts por ubicación. Esta contiene un UserId.
Un diccionario proporciona una correspondencia entre el id de usuario y la ubicación, respaldada por la tabla users:
Omitimos los usuarios con unPara aprovechar este diccionario en el momento de la inserción en la tabla Posts, necesitamos modificar el esquema:Id < 0, lo que nos permite usar el tipo de diccionarioHashed. Los usuarios conId < 0son usuarios del sistema.
Location se declara como una columna MATERIALIZED. Esto significa que el valor puede proporcionarse como parte de una consulta INSERT y que siempre se calculará.
ClickHouse también admite columnas DEFAULT (donde el valor puede insertarse o calcularse si no se proporciona).
Para rellenar la tabla, podemos usar la instrucción habitual INSERT INTO SELECT desde S3:
Temas avanzados sobre diccionarios
Actualización de diccionarios
LIFETIME para el diccionario de MIN 600 MAX 900. LIFETIME es el intervalo de actualización del diccionario, y estos valores hacen que se recargue periódicamente en un intervalo aleatorio de entre 600 y 900 s. Este intervalo aleatorio es necesario para distribuir la carga en el origen del diccionario cuando se actualiza en un gran número de servidores. Durante las actualizaciones, la versión anterior de un diccionario puede seguir consultándose; solo la carga inicial bloquea las consultas. Tenga en cuenta que establecer (LIFETIME(0)) impide que los diccionarios se actualicen.
Los diccionarios pueden recargarse de forma forzada mediante el comando SYSTEM RELOAD DICTIONARY.
Para orígenes de base de datos como ClickHouse y Postgres, puede configurar una consulta que actualice los diccionarios solo si realmente han cambiado (esto lo determina la respuesta de la consulta), en lugar de hacerlo a intervalos periódicos. Puede encontrar más detalles aquí.
Otros tipos de diccionarios
Más información
- Buenas prácticas para diccionarios — elección del layout, diccionarios frente a JOINs, monitorización
- Uso de diccionarios para acelerar las consultas
- Configuración avanzada de diccionarios