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_name 子句之前执行此操作,因为 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 的单个文件
使用 命令行客户端 执行以下查询
结果
使用 glob 的多个文件与 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 或 Buffer 表引擎 导致额外的缓冲。
大型或长时间运行的插入
当你插入大量数据时,ClickHouse 将通过称为“squashing”的过程优化写入性能。内存中的小块插入数据将被合并并压缩成更大的块,然后写入磁盘。Squashing 减少了与每个写入操作相关的开销。在此过程中,插入的数据将在 ClickHouse 完成写入每个 max_insert_block_size 行后可用于查询。
参见