跳到主要内容
跳到主要内容

INSERT INTO 语句

将数据插入表中。

语法

您可以使用 (c1, c2, c3) 指定要插入的列列表。您还可以使用列 匹配器,例如 * 和/或 修饰符,例如 APPLYEXCEPTREPLACE

例如,考虑以下表:

如果您想将数据插入所有列,除了列 b,可以使用 EXCEPT 关键字。根据上述语法,您需要确保插入的值 (VALUES (v11, v13)) 与您指定的列数 ((c1, c3)) 一致:

在这个例子中,我们看到第二个插入的行有 ac 列被填充为传入的值,而 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 格式允许对表达式的有限使用,但不推荐这样做,因为在这种情况下,使用了低效的代码进行执行。

不支持其他修改数据部分的查询: UPDATEDELETEREPLACEMERGEUPSERTINSERT UPDATE。不过,您可以使用 ALTER TABLE ... DROP PARTITION 删除旧数据。

如果 SELECT 子句包含表函数 input(),则必须在查询的末尾指定 FORMAT 子句。

要将默认值插入到非空数据类型的列中以替代 NULL,请启用 insert_null_as_default 设置。

INSERT 还支持 CTE(公用表表达式)。例如,以下两个语句是等价的:

从文件插入数据

语法

使用上述语法从客户端上存储的文件或多个文件插入数据。file_nametype 是字符串文字。输入文件 格式 必须在 FORMAT 子句中设置。

支持压缩文件。压缩类型通过文件名的扩展名检测,或可以在 COMPRESSION 子句中显式指定。支持的类型有:'none''gzip''deflate''br''xz''zstd''lz4''bz2'

此功能在 命令行客户端clickhouse-local 中可用。

示例

单个文件与 FROM INFILE

通过 命令行客户端 执行以下查询:

结果:

使用通配符的多个文件与 FROM INFILE

此示例与前一个示例非常相似,但通过使用 FROM INFILE 'input_*.csv 从多个文件执行插入。

提示

除了使用 * 选择多个文件外,您还可以使用范围({1,2}{1..9})和其他 通配符替换。这三者都可以与上述示例一起使用:

使用表函数插入

数据可以插入到由 表函数 引用的表中。

语法

示例

以下查询中使用了 remote 表函数:

结果:

向 ClickHouse Cloud 插入数据

默认情况下, ClickHouse Cloud 上的服务提供多个副本以保证高可用性。当您连接到服务时,将与这些副本之一建立连接。

INSERT 成功后,数据写入底层存储。然而,副本接收这些更新可能需要一些时间。因此,如果您使用不同的连接在其他副本上执行 SELECT 查询,则可能尚未反映更新的数据。

可以使用 select_sequential_consistency 强制副本接收最新更新。以下是使用此设置的 SELECT 查询示例:

请注意,使用 select_sequential_consistency 会增加 ClickHouse Keeper(ClickHouse Cloud 内部使用)的负载,并可能导致根据服务的负载性能变慢。我们建议在没有必要的情况下不要启用此设置。推荐的方法是在同一会话中执行读/写,或使用支持原生协议的客户端驱动程序(因此支持粘性连接)。

在复制环境中插入

在复制环境中,数据在复制后可见于其他副本。数据从 INSERT 后立即开始复制(下载到其他副本)。这与 ClickHouse Cloud 不同,在 ClickHouse Cloud 中,数据会立即写入共享存储,副本会订阅元数据更改。

请注意,对于复制环境,INSERT 有时可能需要相当长的时间(大约一秒),因为它需要提交到 ClickHouse Keeper 以获得分布式共识。使用 S3 存储也会增加额外的延迟。

性能考虑

INSERT 按主键对输入数据进行排序,并根据分区键将它们拆分为分区。如果您一次向多个分区插入数据,可能会显著降低 INSERT 查询的性能。为了避免这种情况:

  • 每次批量添加相当大的数据,例如 100,000 行。
  • 在上传到 ClickHouse 之前按分区键对数据进行分组。

如果满足以下条件,性能不会下降:

  • 实时添加数据。
  • 您上传的数据通常按时间排序。

异步插入

可以异步插入数据,即进行小而频繁的插入。此类插入的数据会合并成批,然后安全地插入到表中。要使用异步插入,请启用 async_insert 设置。

使用 async_insertBuffer 表引擎 会导致额外的缓存。

大量或长时间插入

当您插入大量数据时,ClickHouse 将通过称为“压缩”的过程优化写入性能。插入的数据小块在内存中被合并和压缩成较大的块,然后写入磁盘。压缩减少了与每次写入操作相关的开销。在此过程中,插入的数据将在 ClickHouse 完成写入每个 max_insert_block_size 行后可供查询。

参见