INSERT ... VALUES simple puede pasar por la cola de inserción asíncrona: INSERT ... SELECT también puede hacerlo. En esta página se describe cuándo ocurre, cómo se contabiliza la parte de escritura y qué sucede cuando la consulta se cancela o supera el tiempo de espera.
Elegibilidad y enrutamiento
UnINSERT ... SELECT sigue la ruta de la cola asíncrona solo cuando se cumplen todas estas condiciones:
async_insert = 1.async_insert_select_as_async_insert = 1(el valor predeterminado). Este es el interruptor principal: si está desactivado,INSERT ... SELECTsiempre es síncrono, independientemente deasync_insert. Si se establececompatibilityen una versión anterior a la 26.10, su valor predeterminado pasa a ser0; para volver a habilitarlo, basta con establecer explícitamenteasync_insert_select_as_async_insert = 1.- Todo el resultado del
SELECTcabe en un único bloque que no superaasync_insert_max_data_size. - El destino es una tabla de la familia
MergeTree(para esta comprobación, un alias se resuelve hasta su destino).
- El resultado ocupa más de un bloque, supera
async_insert_max_data_sizeo está vacío. - Se utiliza quorum no paralelo:
insert_quorumestá establecido einsert_quorum_parallel = 0. - El destino tiene vistas materializadas dependientes.
- El destino es una vista materializada. La comprobación de
MergeTreese aplica a la vista, no a su tabla de destino, por lo que no es elegible. - El destino es una función de tabla o un motor de tabla remoto como
Distributed. - El
SELECTlee de su propia tabla de destino (INSERT INTO t SELECT ... FROM t). insert_null_as_defaulttiene que sustituir por un valor predeterminado los valores de una columnaNullabledelSELECTque alimenta una columna de destino noNullable.- La inserción es interna (actualización de una vista materializada actualizable,
POPULATEoCREATE TABLE ... AS SELECT). Estas inserciones son siempre síncronas e ignoranasync_insert_select_as_async_insertyasync_insert.
implicit_transaction = 1), la ruta asíncrona no es compatible y, de forma predeterminada, ClickHouse lanza NOT_IMPLEMENTED en lugar de recurrir a la ruta síncrona. Solo con throw_on_unsupported_query_inside_transaction = 0 la consulta recurre a una inserción síncrona.
El enrutamiento decidido antes de llegar a la comprobación asíncrona tiene prioridad, por lo que el lado del SELECT puede descartar por sí solo la ruta asíncrona. Con parallel_distributed_insert_select (activado de forma predeterminada), un INSERT ... SELECT que lee de una fuente de cluster como s3Cluster y escribe en una tabla replicada se ejecuta por la ruta de inserción distribuida y nunca llega a la cola asíncrona. Lo mismo ocurre con las réplicas paralelas.
Modo de retorno y espera
wait_for_async_insert funciona igual que en cualquier inserción asíncrona: 1 (el valor predeterminado) espera a que se complete el vaciado; 0 retorna en cuanto el bloque se pone en cola.
Para ayudar a que un SELECT genere el bloque único que exige la ruta asíncrona, optimize_trivial_insert_select limita un INSERT INTO dest SELECT ... FROM source trivial entre tablas distintas a max_insert_threads threads de lectura. Si establece max_insert_threads = 1, el SELECT suele generar un único bloque.
Contabilización de escrituras y observabilidad
La parte de escritura se atribuye a la consulta de vaciado, no alINSERT ... SELECT original:
- La consulta de vaciado registra los
ProfileEventsde escritura (InsertedRows,InsertedBytes) y genera su propia fila de escritura ensystem.query_log. En la fila delINSERT ... SELECToriginal, esosProfileEventsaparecen con valor0. Para ver las cifras de escritura del propio vaciado, consulte su fila ensystem.query_logysystem.asynchronous_insert_log. - Con
wait_for_async_insert = 1(el valor predeterminado), los valoreswritten_rowsywritten_bytesde la consulta (y el encabezado HTTPX-ClickHouse-Summary) reflejan las filas y los bytes aceptados desde elSELECT, no el total de la propia consulta de vaciado. Si el vaciado falla, el error se sigue notificando al client. - Con
wait_for_async_insert = 0, esas cifras no se notifican, ya que la consulta termina antes de que exista el resultado del vaciado. - La cuota
WRITTEN_BYTESse contabiliza una sola vez, en la ruta de vaciado, y no se revierte si el vaciado falla.
Cancelación y tiempos de espera
El bloque se pone en cola antes de que empiece la espera del vaciado, por lo que cancelar la consulta hace que el client deje de esperar, pero no impide que la cola se vacíe.KILL QUERY, o alcanzarmax_execution_timedurante la espera, devuelve un error al client, pero es posible que las filas se escriban igualmente. En esta ruta, una consulta cancelada o que ha agotado el tiempo de espera no es prueba de que no se haya escrito nada.- Con
timeout_overflow_mode = 'break'no se produce ningún error ni retorno anticipado: la consulta espera el vaciado más allá demax_execution_time, hastawait_for_async_insert_timeout. Interrumpir la espera antes de tiempo notificaría un resultado correcto antes de que se confirmara la escritura.
Cuándo se fijan las decisiones
La elegibilidad para la ruta asíncrona se decide una única vez al inicio de la consulta, antes de que el bloque se ponga en cola, y una comprobación de acceso previa rechaza de forma anticipada cualquier inserción no autorizada. Que unINSERT ... SELECT tome o no la ruta asíncrona depende de la forma del bloque resultante, no solo de async_insert.
La búsqueda del destino y la autorización de la vinculación se ejecutan posteriormente, en el momento del vaciado, igual que en cualquier inserción asíncrona: si entre el encolado y el vaciado se asocia una vista materializada al destino o se revoca un privilegio, el vaciado se verá afectado.