INSERT INTO 语句
向表中插入数据。
语法
您可以使用 (c1, c2, c3)
指定要插入的列列表。您还可以使用带有列 匹配器 的表达式,例如 *
和/或 修饰符,例如 APPLY、 EXCEPT 和 REPLACE。
例如,考虑以下表:
如果您想向除列 b
之外的所有列插入数据,可以使用 EXCEPT
关键字。根据上述语法,您需要确保插入的值数量 (VALUES (v11, v13)
) 与您指定的列数量 ((c1, c3)
) 相匹配:
在这个例子中,我们看到第二个被插入的行有 a
和 c
列由传递的值填充,而 b
列则填充了默认值。还可以使用 DEFAULT
关键字插入默认值:
如果列列表不包含所有现有的列,则其余列将填充如下:
- 从表定义中指定的
DEFAULT
表达式计算出的值。 - 如果没有定义
DEFAULT
表达式,则为零和空字符串。
数据可以以 ClickHouse 支持的任何 格式 传递给 INSERT。格式必须在查询中明确指定:
例如,以下查询格式与 INSERT ... VALUES
的基本版本相同:
ClickHouse 会在数据之前删除所有空格和一行换行符(如果存在)。在形成查询时,我们建议将数据放在查询运算符之后的新行上,这对于数据以空格开头的情况非常重要。
示例:
您可以使用 命令行客户端 或 HTTP 接口 单独插入数据。
如果您想为 INSERT
查询指定 SETTINGS
,则必须在 FORMAT
子句之前进行,因为在 FORMAT format_name
之后的所有内容都被视为数据。例如:
约束
如果表具有 约束,则会检查每一行插入数据的表达式。如果违反任何一个约束 - 服务器将引发包含约束名称和表达式的异常,并停止查询。
从 SELECT 插入结果
语法
列根据 SELECT
子句中的位置进行映射。然而,SELECT
表达式和 INSERT
表中的表的名称可能不同。如有必要,执行类型转换。
除了 Values 格式外,没有其他数据格式允许设置如 now()
、1 + 2
等表达式的值。Values 格式允许有限地使用表达式,但这并不推荐,因为在这种情况下会使用低效的代码进行执行。
不支持其他修改数据部分的查询:UPDATE
、DELETE
、REPLACE
、MERGE
、UPSERT
、INSERT UPDATE
。但是,您可以使用 ALTER TABLE ... DROP PARTITION
删除旧数据。
如果 SELECT
子句包含表函数 input(),则 FORMAT
子句必须在查询的末尾指定。
要向具有非空数据类型的列插入默认值而不是 NULL
,请启用 insert_null_as_default 设置。
INSERT
还支持 CTE(公共表表达式)。例如,以下两个语句是等效的:
从文件插入数据
语法
使用上述语法从存储在 客户端 侧的文件或文件中插入数据。file_name
和 type
是字符串字面量。输入文件 格式 必须在 FORMAT
子句中设置。
支持压缩文件。压缩类型由文件名扩展名检测,或可以在 COMPRESSION
子句中明确指定。支持的类型包括: 'none'
、'gzip'
、'deflate'
、'br'
、'xz'
、'zstd'
、'lz4'
、'bz2'
。
此功能在 命令行客户端 和 clickhouse-local 中可用。
示例
使用 FROM INFILE 的单个文件
使用 命令行客户端 执行以下查询:
结果:
使用通配符从多个文件插入数据
此示例与前一个示例非常相似,但使用 FROM INFILE 'input_*.csv
从多个文件中执行插入。
使用表函数插入
数据可以插入到 表函数 引用的表中。
语法
示例
在以下查询中使用了 remote 表函数:
结果:
插入到 ClickHouse Cloud
默认情况下,ClickHouse Cloud 上的服务提供多个副本以实现高可用性。当您连接到服务时,会与这些副本之一建立连接。
在 INSERT
成功后,数据会写入底层存储。然而,副本接收这些更新可能需要一些时间。因此,如果您使用另一个连接在其他副本之一上执行 SELECT
查询,则更新的数据可能尚未反映。
可以使用 select_sequential_consistency
强制副本接收最新更新。以下是使用此设置的 SELECT
查询示例:
请注意,使用 select_sequential_consistency
会增加 ClickHouse Keeper(ClickHouse Cloud 内部使用)上的负载,并可能导致性能下降,具体取决于服务的负载。我们建议在非必要情况下不要启用此设置。推荐的方法是在同一会话中执行读/写,或者使用使用原生协议的客户端驱动程序(因此支持粘性连接)。
插入到复制设置中
在复制设置中,在数据被复制后,其他副本上将可见。数据在 INSERT
后立即开始复制(在其他副本上下载)。这与 ClickHouse Cloud 不同,后者数据会立即写入共享存储,副本订阅元数据更改。
请注意,对于复制设置,INSERT
有时可能需要相当长的时间(约一秒钟),因为它需要向 ClickHouse Keeper 提交以进行分布式共识。使用 S3 进行存储也增加了额外的延迟。
性能考虑
INSERT
会根据主键对输入数据进行排序,并按分区键将其拆分为分区。如果您同时向多个分区插入数据,可能会显著降低 INSERT
查询的性能。为了避免这种情况:
- 在相当大的批次中添加数据,例如每次 100,000 行。
- 在将数据上传到 ClickHouse 之前,按分区键对数据进行分组。
如果满足以下条件,性能将不会降低:
- 实时添加数据。
- 您上传的数据通常按时间排序。
异步插入
可以以小批量但频繁的方式异步插入数据。这类插入的数据会合并为批次,然后安全地插入到表中。要使用异步插入,请启用 async_insert
设置。
使用 async_insert
或 Buffer
表引擎 会导致额外的缓冲。
大型或长时间运行的插入
当插入大量数据时,ClickHouse 将通过称为 “压缩” 的过程优化写入性能。内存中插入的小块数据会合并并压缩为更大的块,然后再写入磁盘。压缩减少了与每次写入操作相关的开销。在此过程中,插入的数据将在 ClickHouse 完成写入每个 max_insert_block_size
行后可供查询。
另请参见