Las actualizaciones ligeras se encuentran actualmente en fase beta.
Si tienes algún problema, abre una incidencia en el repositorio de ClickHouse.
UPDATE actualiza las filas de una tabla [db.]table que coinciden con la expresión filter_expr.
Se denomina “actualización ligera” para diferenciarla de la consulta ALTER TABLE ... UPDATE, que es un proceso costoso que reescribe columnas completas en las partes de datos.
Solo está disponible para la familia de motores de tabla MergeTree.
filter_expr debe ser de tipo UInt8. Esta consulta actualiza los valores de las columnas especificadas con los valores de las expresiones correspondientes en las filas en las que filter_expr toma un valor distinto de cero.
Los valores se convierten al tipo de la columna mediante el operador CAST. No se admite la actualización de columnas utilizadas en el cálculo de las claves primarias o de partición.
La cláusula IN PARTITION limita la actualización a las particiones indicadas. Sin ella, en las tablas de la familia ReplicatedMergeTree, cuando el ajuste optimize_mutations_with_partition_pruning está habilitado (valor predeterminado), ClickHouse detecta automáticamente las condiciones sobre la clave de partición en filter_expr y solo actualiza las particiones afectadas. En tablas MergeTree no replicadas, usa una cláusula IN PARTITION explícita para limitar una actualización a particiones concretas.
Ejemplos
Las actualizaciones ligeras son visibles de inmediato en las consultas
La actualización ligera (UPDATE) hace que los valores actualizados sean visibles de inmediato en las consultas SELECT mediante la aplicación de partes de parche. Las consultas no necesitan esperar a una fusión para leer los valores actualizados.
Los partes de parche son un tipo especial de parte de datos que contiene únicamente las columnas y filas actualizadas. Su creación no modifica físicamente de inmediato los datos originales en el almacenamiento.
El proceso de actualización es similar a una consulta INSERT ... SELECT ..., y la consulta UPDATE espera a que finalice la creación de la parte de parche antes de devolver el control.
La visibilidad en las consultas y la materialización física son procesos independientes:
- Visibilidad en las consultas: las consultas
SELECTaplican los parches para leer los valores actualizados antes de que dichos parches se materialicen en las partes de datos originales. - Materialización física: las fusiones y mutaciones posteriores incorporan los valores actualizados a las partes de datos.
- Limpieza: las partes de parche se eliminan automáticamente en cuanto todas las partes activas tienen los parches materializados.
Requisitos de las actualizaciones ligeras
Las actualizaciones ligeras son compatibles con los motoresMergeTree, ReplacingMergeTree, CollapsingMergeTree y VersionedCollapsingMergeTree, así como con sus versiones Replicated y Shared.
Para usar actualizaciones ligeras, la materialización de las columnas _block_number y _block_offset debe habilitarse mediante las opciones de configuración de la tabla enable_block_number_column y enable_block_offset_column.
Eliminaciones ligeras
Una consulta de eliminación ligeraDELETE puede ejecutarse como una actualización ligera UPDATE en lugar de una mutación ALTER UPDATE. La implementación de la eliminación ligera DELETE se controla mediante el ajuste lightweight_delete_mode.
Consideraciones de rendimiento
- La latencia de la actualización es comparable a la de la consulta
INSERT ... SELECT ... - Solo se escriben las columnas y los valores actualizados, no columnas completas en las partes de datos
- No es necesario esperar a que terminen las fusiones o mutaciones en ejecución; por lo tanto, la latencia de una actualización es predecible
- Es posible ejecutar actualizaciones ligeras en paralelo
- Añaden una sobrecarga a las consultas
SELECTque necesitan aplicar parches - Los índices de omisión no se usarán para las columnas de partes de datos que tengan parches pendientes de aplicar. Las proyecciones no se usarán si la tabla tiene partes de parche, incluso en las partes de datos que no tengan parches pendientes de aplicar.
- Las actualizaciones pequeñas demasiado frecuentes pueden provocar un error “Too many parts”. Se recomienda agrupar varias actualizaciones en una sola consulta, por ejemplo, incluyendo los ID de las actualizaciones en una sola cláusula
INdentro de la cláusulaWHERE - Las actualizaciones ligeras están diseñadas para actualizar pequeñas cantidades de filas (hasta aproximadamente el 10 % de la tabla). Si necesita actualizar una cantidad mayor, se recomienda usar la mutación
ALTER TABLE ... UPDATE
Operaciones concurrentes
Las actualizaciones ligeras, a diferencia de las mutaciones tradicionales, no esperan a que finalicen las fusiones/mutaciones que están en ejecución. La consistencia de las actualizaciones ligeras concurrentes se controla mediante la configuraciónupdate_sequential_consistency y update_parallel_mode.
Actualizar permisos
UPDATE requiere el privilegio ALTER UPDATE. Para habilitar las sentencias UPDATE en una tabla específica para un usuario concreto, ejecute:
Detalles de la implementación
_part- el nombre de la parte original_part_offset- el número de fila en la parte original_block_number- el número de bloque de la fila en la parte original_block_offset- el desplazamiento del bloque de la fila en la parte original_data_version- la versión de los datos actualizados (número de bloque asignado a la consultaUPDATE)
_part y _part_offset.
Las partes de parche pertenecen a particiones distintas de la parte original.
El ID de partición de la parte de parche es patch-<hash of column names in patch part>-<original_partition_id>.
Por lo tanto, las partes de parche con columnas diferentes se almacenan en particiones distintas.
Por ejemplo, tres actualizaciones SET x = 1 WHERE <cond>, SET y = 1 WHERE <cond> y SET x = 1, y = 1 WHERE <cond> crearán tres partes de parche en tres particiones distintas.
Las partes de parche pueden fusionarse entre sí para reducir la cantidad de parches aplicados en las consultas SELECT y disminuir la sobrecarga. La fusión de partes de parche usa el algoritmo de fusión replacing con _data_version como columna de versión.
Por lo tanto, las partes de parche siempre almacenan la versión más reciente de cada fila actualizada de la parte.
Las actualizaciones ligeras no esperan a que terminen las fusiones y mutaciones que se estén ejecutando en ese momento, y siempre usan una instantánea actual de las partes de datos para ejecutar una actualización y generar una parte de parche.
Por eso, puede haber dos casos al aplicar partes de parche.
Por ejemplo, si leemos la parte A, necesitamos aplicar la parte de parche X:
- si
Xcontiene la propia parteA. Esto ocurre siAno estaba participando en una fusión cuando se ejecutóUPDATE. - si
Xcontiene las partesByC, que están cubiertas por la parteA. Esto ocurre si había una fusión (B,C) ->Aen ejecución cuando se ejecutóUPDATE.
- Usar una fusión por las columnas ordenadas
_part,_part_offset. - Usar join por las columnas
_block_number,_block_offset.
Contenido relacionado
ALTER UPDATE- OperacionesUPDATEde alto costo- eliminación ligera - Operaciones de eliminación ligera con
DELETE APPLY PATCHES- Forzar la materialización física de los parches en las partes de datos (operación de mutación)