跳到主要内容
跳到主要内容
编辑此页

查询复杂度限制

查询复杂度限制是设置的一部分。它们用于从用户界面提供更安全的执行。几乎所有限制仅适用于 SELECT。对于分布式查询处理,限制在每个服务器上单独应用。

ClickHouse 检查数据部分的限制,而不是每行的限制。这意味着您可能会因数据部分的大小而超出限制值。

关于“最大数量”的限制可以取值 0,这意味着“无限制”。大多数限制还具有 'overflow_mode' 设置,表示超出限制时要执行的操作。它可以取两个值之一:throwbreak。聚合的限制 (group_by_overflow_mode) 也有值 any

throw – 抛出异常(默认)。

break – 停止执行查询并返回部分结果,就像源数据耗尽一样。

any (仅用于 group_by_overflow_mode) – 继续对已进入集合的键进行聚合,但不向集合添加新键。

max_memory_usage

在单个服务器上运行查询时使用的最大 RAM 量。

默认设置是无限制的(设置为 0)。

云默认值:取决于副本上的 RAM 量。

此设置不考虑可用内存量或机器上的总内存量。此限制适用于单个服务器内的单个查询。您可以使用 SHOW PROCESSLIST 查看每个查询的当前内存消耗。此外,每个查询的峰值内存消耗都会被跟踪并写入日志。

对于某些聚合函数的状态,不会监控内存使用情况。

对于来自 StringArray 参数的聚合函数 minmaxanyanyLastargMinargMax 的状态,内存使用情况未被完全跟踪。

内存消耗也受到参数 max_memory_usage_for_usermax_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