查询复杂度限制
查询复杂度限制是设置的一部分。它们用于从用户界面提供更安全的执行。几乎所有限制仅适用于 SELECT
。对于分布式查询处理,限制在每个服务器上单独应用。
ClickHouse 检查数据部分的限制,而不是每行的限制。这意味着您可能会因数据部分的大小而超出限制值。
关于“最大数量”的限制可以取值 0,这意味着“无限制”。大多数限制还具有 'overflow_mode' 设置,表示超出限制时要执行的操作。它可以取两个值之一:throw
或 break
。聚合的限制 (group_by_overflow_mode) 也有值 any
。
throw
– 抛出异常(默认)。
break
– 停止执行查询并返回部分结果,就像源数据耗尽一样。
any (仅用于 group_by_overflow_mode)
– 继续对已进入集合的键进行聚合,但不向集合添加新键。
max_memory_usage
在单个服务器上运行查询时使用的最大 RAM 量。
默认设置是无限制的(设置为 0
)。
云默认值:取决于副本上的 RAM 量。
此设置不考虑可用内存量或机器上的总内存量。此限制适用于单个服务器内的单个查询。您可以使用 SHOW PROCESSLIST
查看每个查询的当前内存消耗。此外,每个查询的峰值内存消耗都会被跟踪并写入日志。
对于某些聚合函数的状态,不会监控内存使用情况。
对于来自 String
和 Array
参数的聚合函数 min
、max
、any
、anyLast
、argMin
、argMax
的状态,内存使用情况未被完全跟踪。
内存消耗也受到参数 max_memory_usage_for_user
和 max_server_memory_usage 的限制。
max_memory_usage_for_user
在单个服务器上运行用户查询时使用的最大 RAM 量。
默认值在 Settings.h 中定义。默认情况下,该数量不受限制 (`max_memory_usage_for_user = 0`)。
另请参阅 max_memory_usage 的描述。
例如,如果您想为名为 `clickhouse_read` 的用户将 `max_memory_usage_for_user` 设置为 1000 字节,则可以使用以下语句
ALTER USER clickhouse_read SETTINGS max_memory_usage_for_user = 1000;
您可以通过注销客户端,重新登录,然后使用 `getSetting` 函数来验证它是否有效
SELECT getSetting('max_memory_usage_for_user');
max_rows_to_read
以下限制可以在每个块上检查(而不是在每行上)。也就是说,限制可能会稍微被突破。
运行查询时可以从表中读取的最大行数。
max_bytes_to_read
运行查询时可以从表中读取的最大字节数(未压缩数据)。
read_overflow_mode
当读取的数据量超过其中一个限制时要执行的操作:“throw”或“break”。 默认情况下,为 throw。
max_rows_to_read_leaf
以下限制可以在每个块上检查(而不是在每行上)。也就是说,限制可能会稍微被突破。
运行分布式查询时,可以从叶节点上的本地表读取的最大行数。虽然分布式查询可以向每个分片(叶节点)发出多个子查询 - 此限制仅在叶节点上的读取阶段进行检查,而在根节点上的结果合并阶段将被忽略。 例如,集群由 2 个分片组成,每个分片包含一个有 100 行的表。然后,分布式查询旨在读取两个表中的所有数据,设置 `max_rows_to_read=150` 将失败,因为总共有 200 行。而设置 `max_rows_to_read_leaf=150` 的查询将成功,因为叶节点最多读取 100 行。
max_bytes_to_read_leaf
运行分布式查询时,可以从叶节点上的本地表读取的最大字节数(未压缩数据)。虽然分布式查询可以向每个分片(叶节点)发出多个子查询 - 此限制仅在叶节点上的读取阶段进行检查,而在根节点上的结果合并阶段将被忽略。 例如,集群由 2 个分片组成,每个分片包含一个有 100 字节数据的表。然后,分布式查询旨在读取两个表中的所有数据,设置 `max_bytes_to_read=150` 将失败,因为总共有 200 字节。而设置 `max_bytes_to_read_leaf=150` 的查询将成功,因为叶节点最多读取 100 字节。
read_overflow_mode_leaf
当读取的数据量超过其中一个叶节点限制时要执行的操作:“throw”或“break”。 默认情况下,为 throw。
max_rows_to_group_by
从聚合接收到的唯一键的最大数量。此设置允许您限制聚合时的内存消耗。
group_by_overflow_mode
当聚合的唯一键数量超过限制时要执行的操作:“throw”、“break”或“any”。 默认情况下,为 throw。使用 'any' 值允许您运行 GROUP BY 的近似值。此近似值的质量取决于数据的统计性质。
max_bytes_before_external_group_by
启用或禁用在外部内存中执行 `GROUP BY` 子句。请参阅 外部内存中的 GROUP BY。
可能的值
- 单个 GROUP BY 操作可以使用的最大 RAM 量(以字节为单位)。
- 0 — 禁用外部内存中的 `GROUP BY`。
默认值:`0`。
云默认值:每个副本内存量的一半。
max_bytes_ratio_before_external_group_by
允许 `GROUP BY` 使用的可用内存的比率,一旦达到,则使用外部内存进行聚合。
例如,如果设置为 `0.6`,`GROUP BY` 将允许在执行开始时使用 `60%` 的可用内存(用于服务器/用户/合并),之后,它将开始使用外部聚合。
默认值:`0.5`。
max_bytes_before_external_sort
启用或禁用在外部内存中执行 `ORDER BY` 子句。请参阅 ORDER BY 实现细节
- 单个 ORDER BY 操作可以使用的最大 RAM 量(以字节为单位)。 推荐值为可用系统内存的一半
- 0 — 禁用外部内存中的 `ORDER BY`。
默认值:0。
云默认值:每个副本内存量的一半。
max_bytes_ratio_before_external_sort
允许 `ORDER BY` 使用的可用内存的比率,一旦达到,则使用外部排序。
例如,如果设置为 `0.6`,`ORDER BY` 将允许在执行开始时使用 `60%` 的可用内存(用于服务器/用户/合并),之后,它将开始使用外部排序。
默认值:`0.5`。
max_rows_to_sort
排序之前的最大行数。这允许您限制排序时的内存消耗。
max_bytes_to_sort
排序之前的最大字节数。
sort_overflow_mode
如果排序之前收到的行数超过其中一个限制,则要执行的操作:“throw”或“break”。 默认情况下,为 throw。
max_result_rows
结果中的行数限制。 也会在子查询中以及在远程服务器上运行分布式查询的部分时检查。当值为 `0` 时,不应用限制。
默认值:`0`。
云默认值:`0`。
max_result_bytes
结果中的字节数限制。 与上一个设置相同。
result_overflow_mode
如果结果量超过其中一个限制,则要执行的操作:“throw”或“break”。
使用 'break' 类似于使用 LIMIT。 `Break` 仅在块级别中断执行。 这意味着返回的行数大于 max_result_rows,是 max_block_size 的倍数,并且取决于 max_threads。
默认值:`throw`。
云默认值:`throw`。
示例
SET max_threads = 3, max_block_size = 3333;
SET max_result_rows = 3334, result_overflow_mode = 'break';
SELECT *
FROM numbers_mt(100000)
FORMAT Null;
结果
6666 rows in set. ...
max_execution_time
最大查询执行时间,以秒为单位。此时,不会检查排序阶段之一,或者合并和最终确定聚合函数时。
`max_execution_time` 参数可能有点难以理解。它基于相对于当前查询执行速度的插值进行操作(此行为由 timeout_before_checking_execution_speed 控制)。如果预计的执行时间超过指定的 `max_execution_time`,ClickHouse 将中断查询。默认情况下,timeout_before_checking_execution_speed 设置为 10 秒。这意味着在查询执行 10 秒后,ClickHouse 将开始估计总执行时间。 例如,如果 `max_execution_time` 设置为 3600 秒(1 小时),如果估计时间超过此 3600 秒限制,ClickHouse 将终止查询。如果您将 `timeout_before_checking_execution_speed ` 设置为 0,ClickHouse 将使用时钟时间作为 `max_execution_time` 的基础。
timeout_overflow_mode
如果查询运行时间超过 `max_execution_time` 或估计运行时间超过 `max_estimated_execution_time`,则要执行的操作:`throw` 或 `break`。 默认情况下,为 `throw`。
max_execution_time_leaf
与 `max_execution_time` 语义相似,但仅适用于分布式或远程查询的叶节点。
例如,如果我们想将叶节点上的执行时间限制为 `10s`,但对初始节点没有限制,而不是在嵌套子查询设置中设置 `max_execution_time`
SELECT count() FROM cluster(cluster, view(SELECT * FROM t SETTINGS max_execution_time = 10));
我们可以使用 `max_execution_time_leaf` 作为查询设置
SELECT count() FROM cluster(cluster, view(SELECT * FROM t)) SETTINGS max_execution_time_leaf = 10;
timeout_overflow_mode_leaf
当叶节点中的查询运行时间超过 `max_execution_time_leaf` 时要执行的操作:`throw` 或 `break`。 默认情况下,为 `throw`。
min_execution_speed
每秒最小执行速度,以行数为单位。 当 'timeout_before_checking_execution_speed' 过期时,在每个数据块上检查。 如果执行速度较低,则会抛出异常。
min_execution_speed_bytes
每秒最小执行字节数。 当 'timeout_before_checking_execution_speed' 过期时,在每个数据块上检查。 如果执行速度较低,则会抛出异常。
max_execution_speed
每秒最大执行行数。 当 'timeout_before_checking_execution_speed' 过期时,在每个数据块上检查。 如果执行速度过高,则会降低执行速度。
max_execution_speed_bytes
每秒最大执行字节数。 当 'timeout_before_checking_execution_speed' 过期时,在每个数据块上检查。 如果执行速度过高,则会降低执行速度。
timeout_before_checking_execution_speed
在指定的秒数过后,检查执行速度是否不太慢(不低于 'min_execution_speed')。
max_estimated_execution_time
最大查询估计执行时间,以秒为单位。 当 'timeout_before_checking_execution_speed' 过期时,在每个数据块上检查。
max_columns_to_read
单个查询中可以从表中读取的最大列数。 如果查询需要读取更多列,则会抛出异常。
max_temporary_columns
运行查询时必须同时保存在 RAM 中的临时列的最大数量,包括常量列。 如果临时列的数量超过此值,则会抛出异常。
max_temporary_non_const_columns
与 'max_temporary_columns' 相同,但不计算常量列。 请注意,常量列在运行查询时经常形成,但它们几乎不需要计算资源。
max_subquery_depth
子查询的最大嵌套深度。 如果子查询更深,则会抛出异常。 默认情况下为 100。
max_pipeline_depth
最大管道深度。 对应于每个数据块在查询处理期间经历的转换次数。 在单个服务器的限制内计数。 如果管道深度更大,则会抛出异常。 默认情况下为 1000。
max_ast_depth
查询语法树的最大嵌套深度。 如果超过此值,则会抛出异常。 此时,它不会在解析期间检查,而仅在解析查询后检查。 也就是说,在解析期间可能会创建太深的语法树,但查询将失败。 默认情况下为 1000。
max_ast_elements
查询语法树中的最大元素数。 如果超过此值,则会抛出异常。 与上一个设置相同,它仅在解析查询后检查。 默认情况下为 50,000。
max_rows_in_set
从子查询创建的 IN 子句中数据集的最大行数。
max_bytes_in_set
从子查询创建的 IN 子句中集合使用的最大字节数(未压缩数据)。
set_overflow_mode
当数据量超过其中一个限制时要执行的操作:“throw”或“break”。 默认情况下,为 throw。
max_rows_in_distinct
使用 DISTINCT 时的最大不同行数。
max_bytes_in_distinct
使用 DISTINCT 时哈希表使用的最大字节数。
distinct_overflow_mode
当数据量超过其中一个限制时要执行的操作:“throw”或“break”。 默认情况下,为 throw。
max_rows_to_transfer
使用 GLOBAL IN 时,可以传递到远程服务器或保存在临时表中的最大行数。
max_bytes_to_transfer
使用 GLOBAL IN 时,可以传递到远程服务器或保存在临时表中的最大字节数(未压缩数据)。
transfer_overflow_mode
当数据量超过其中一个限制时要执行的操作:“throw”或“break”。 默认情况下,为 throw。
max_rows_in_join
限制在连接表时使用的哈希表中的最大行数。
此设置适用于 SELECT ... JOIN 操作和 Join 表引擎。
如果查询包含多个连接,ClickHouse 会为每个中间结果检查此设置。
当达到限制时,ClickHouse 可以继续执行不同的操作。 使用 join_overflow_mode 设置来选择操作。
可能的值
- 正整数。
- 0 — 无限制的行数。
默认值:0。
max_bytes_in_join
限制连接表时使用的哈希表的大小(以字节为单位)。
此设置适用于 SELECT ... JOIN 操作和 Join 表引擎。
如果查询包含连接,ClickHouse 会为每个中间结果检查此设置。
当达到限制时,ClickHouse 可以继续执行不同的操作。 使用 join_overflow_mode 设置来选择操作。
可能的值
- 正整数。
- 0 — 禁用内存控制。
默认值:0。
join_overflow_mode
定义当达到以下任何连接限制时 ClickHouse 执行的操作
可能的值
THROW
— ClickHouse 抛出异常并中断操作。BREAK
— ClickHouse 中断操作,但不抛出异常。
默认值:THROW
。
参见
max_partitions_per_insert_block
限制单个插入块中的最大分区数。
- 正整数。
- 0 — 无限制的分区数。
默认值:100。
详情
插入数据时,ClickHouse 会计算插入块中的分区数。 如果分区数超过 max_partitions_per_insert_block
,ClickHouse 会根据 throw_on_max_partitions_per_insert_block
记录警告或抛出异常。 异常具有以下文本
“单个 INSERT 块的分区过多 (
partitions_count
个分区,限制为 ” + toString(max_partitions) + “)。 该限制由 ‘max_partitions_per_insert_block’ 设置控制。 大量的分区是一种常见的误解。 它将导致严重的负面性能影响,包括服务器启动缓慢、INSERT 查询缓慢和 SELECT 查询缓慢。 表的建议总分区数在 1000..10000 以下。 请注意,分区并非旨在加速 SELECT 查询(ORDER BY 键足以使范围查询快速)。 分区旨在用于数据操作(DROP PARTITION 等)。”
throw_on_max_partitions_per_insert_block
允许您控制达到 max_partitions_per_insert_block
时的行为。
true
- 当插入块达到max_partitions_per_insert_block
时,会引发异常。false
- 当达到max_partitions_per_insert_block
时,记录警告。
默认值:true
max_temporary_data_on_disk_size_for_user
所有并发运行的用户查询在磁盘上临时文件消耗的最大数据量(以字节为单位)。 零表示无限制。
默认值:0。
max_temporary_data_on_disk_size_for_query
所有并发运行的查询在磁盘上临时文件消耗的最大数据量(以字节为单位)。 零表示无限制。
默认值:0。
max_sessions_for_user
每个已验证用户到 ClickHouse 服务器的最大同时会话数。
示例
<profiles>
<single_session_profile>
<max_sessions_for_user>1</max_sessions_for_user>
</single_session_profile>
<two_sessions_profile>
<max_sessions_for_user>2</max_sessions_for_user>
</two_sessions_profile>
<unlimited_sessions_profile>
<max_sessions_for_user>0</max_sessions_for_user>
</unlimited_sessions_profile>
</profiles>
<users>
<!-- User Alice can connect to a ClickHouse server no more than once at a time. -->
<Alice>
<profile>single_session_user</profile>
</Alice>
<!-- User Bob can use 2 simultaneous sessions. -->
<Bob>
<profile>two_sessions_profile</profile>
</Bob>
<!-- User Charles can use arbitrarily many of simultaneous sessions. -->
<Charles>
<profile>unlimited_sessions_profile</profile>
</Charles>
</users>
默认值:0(无限数量的并发会话)。
max_partitions_to_read
限制一个查询中可以访问的最大分区数。
创建表时指定的设置值可以通过查询级设置覆盖。
可能的值
- 任何正整数。
默认值:-1(无限制)。
您还可以在表的设置中指定 MergeTree 设置 max_partitions_to_read。