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.
Ejemplos
Las actualizaciones ligeras no actualizan los datos inmediatamente
UPDATE se implementa mediante partes de parche, un tipo especial de parte de datos que contiene solo las columnas y filas actualizadas.
Una actualización ligera UPDATE crea partes de parche, pero no modifica físicamente de inmediato los datos originales en el almacenamiento.
El proceso de actualización es similar al de una consulta INSERT ... SELECT ..., pero la consulta UPDATE espera a que se complete la creación de la parte de parche antes de devolver el control.
Los valores actualizados quedan:
- Inmediatamente visibles en las consultas
SELECTmediante la aplicación de parches - Materializados físicamente solo durante fusiones y mutaciones posteriores
- Eliminados automáticamente una vez que todas las partes activas tienen los parches materializados
Requisitos de las actualizaciones ligeras
MergeTree, 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
DELETE 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
update_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.
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)