> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# optimize_* 会话设置

> ClickHouse 的 optimize_* 自动生成组中的会话设置。

export const SettingsInfoBlock = ({type, default_value, changeable_without_restart}) => {
  return <div className="not-prose" style={{
    display: "flex",
    flexWrap: "wrap",
    alignItems: "baseline",
    columnGap: "0.5rem",
    rowGap: "0.125rem",
    margin: "0.375rem 0",
    fontSize: "0.8125rem",
    lineHeight: "1.125rem"
  }}>
      <div style={{
    fontWeight: 600,
    opacity: 0.72
  }}>类型</div>
      <div style={{
    overflowWrap: "anywhere"
  }}>{type}</div>
      <div style={{
    fontWeight: 600,
    opacity: 0.72,
    marginInlineStart: "0.5rem"
  }}>默认值</div>
      <div style={{
    overflowWrap: "anywhere"
  }}>{default_value}</div>
      {changeable_without_restart && <div style={{
    fontWeight: 600,
    opacity: 0.72,
    marginInlineStart: "0.5rem"
  }}>
          无需重启即可更改
        </div>}
      {changeable_without_restart && <div style={{
    overflowWrap: "anywhere"
  }}>
          {changeable_without_restart}
        </div>}
    </div>;
};

这些设置可在 [system.settings](/docs/zh/reference/system-tables/settings) 中找到，并由 [源代码](https://github.com/ClickHouse/ClickHouse/blob/master/src/Core/Settings.cpp) 自动生成。

<div id="optimize_aggregators_of_group_by_keys">
  ## optimize\_aggregators\_of\_group\_by\_keys
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

消除 SELECT 部分中对 GROUP BY 键使用的 min/max/any/anyLast 聚合函数

<div id="optimize_append_index">
  ## optimize\_append\_index
</div>

<SettingsInfoBlock type="Bool" default_value="0" />

使用 [约束](/docs/zh/reference/statements/create/table#constraints) 来附加索引条件。默认值为 `false`。

可能的值：

* true, false

<div id="optimize_arithmetic_operations_in_aggregate_functions">
  ## optimize\_arithmetic\_operations\_in\_aggregate\_functions
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

将算术运算移到聚合函数之外

<div id="optimize_const_name_size">
  ## optimize\_const\_name\_size
</div>

<SettingsInfoBlock type="Int64" default_value="256" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "25.11"},{"label": "256"},{"label": "替换为标量，并对较大的常量使用哈希作为名称（大小按名称长度估算）"}]}]} />

替换为标量，并对较大的常量使用哈希作为名称 (大小按名称长度估算) 。

可能的取值：

* 正整数 - 名称的最大长度，
* 0 — 始终，
* 负整数 - 从不。

<div id="optimize_count_from_files">
  ## optimize\_count\_from\_files
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

启用或禁用针对不同输入格式文件的行数统计优化。适用于表函数/引擎 `file`/`s3`/`url`/`hdfs`/`azureBlobStorage`。

可能的值：

* 0 — 禁用优化。
* 1 — 启用优化。

<div id="optimize_dictget_tuple_element">
  ## optimize\_dictget\_tuple\_element
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "26.5"},{"label": "1"},{"label": "将 tupleElement(dictGet(..., tuple_of_attrs, ...), N) 改写为单属性 dictGet 调用。"}]}]} />

将 `tupleElement(dictGet('dict', ('a', 'b', 'c'), key), 2)` 改写为 `dictGet('dict', 'b', key)`，以避免拉取不必要的字典属性。支持按位置 (`.1`、`.2`、...) 和按名称 (`.b`) 访问，也适用于 `dictGetOrDefault`，前提是默认参数为常量 Tuple 或由常量组成的 `tuple(...)`。

<div id="optimize_distinct_in_order">
  ## optimize\_distinct\_in\_order
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

如果 DISTINCT 中的某些列构成排序前缀，则启用 DISTINCT 优化。例如，MergeTree 中 sorting key 的前缀，或 ORDER BY 语句中的前缀。

<div id="optimize_distributed_group_by_sharding_key">
  ## optimize\_distributed\_group\_by\_sharding\_key
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

通过避免在发起服务器上执行高开销的聚合，优化 `GROUP BY sharding_key` 查询 (这将降低该查询在发起服务器上的内存使用) 。

支持以下类型的查询 (以及它们的任意组合) ：

* `SELECT DISTINCT [..., ]sharding_key[, ...] FROM dist`
* `SELECT ... FROM dist GROUP BY sharding_key[, ...]`
* `SELECT ... FROM dist GROUP BY sharding_key[, ...] ORDER BY x`
* `SELECT ... FROM dist GROUP BY sharding_key[, ...] LIMIT 1`
* `SELECT ... FROM dist GROUP BY sharding_key[, ...] LIMIT 1 BY x`

不支持以下类型的查询 (其中部分查询后续可能会增加支持) ：

* `SELECT ... GROUP BY sharding_key[, ...] WITH TOTALS`
* `SELECT ... GROUP BY sharding_key[, ...] WITH ROLLUP`
* `SELECT ... GROUP BY sharding_key[, ...] WITH CUBE`
* `SELECT ... GROUP BY sharding_key[, ...] SETTINGS extremes=1`

可能的值：

* 0 — 禁用。
* 1 — 启用。

另请参见：

* [distributed\_group\_by\_no\_merge](/docs/zh/reference/settings/session-settings/distributed#distributed_group_by_no_merge)
* [distributed\_push\_down\_limit](/docs/zh/reference/settings/session-settings/distributed#distributed_push_down_limit)
* [optimize\_skip\_unused\_shards](/docs/zh/reference/settings/session-settings/optimize-skip#optimize_skip_unused_shards)

<Note>
  目前它要求启用 `optimize_skip_unused_shards` (原因是未来某一天它可能会默认启用，而它只有在数据是通过 Distributed 表插入时才能正确工作，也就是说，数据必须按 `sharding_key` 分布) 。
</Note>

<div id="optimize_dry_run_check_part">
  ## optimize\_dry\_run\_check\_part
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "26.2"},{"label": "1"},{"label": "新设置"}]}]} />

启用后，`OPTIMIZE ... DRY RUN` 会使用 `checkDataPart` 对生成的合并后分片进行校验。如果校验失败，则会抛出异常。

<div id="optimize_empty_string_comparisons">
  ## optimize\_empty\_string\_comparisons
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "25.10"},{"label": "1"},{"label": "新设置。"}]}]} />

仅当 `col` 为 String 或 FixedString 类型时，才会将 `col = ''` 或 `'' = col` 之类的表达式转换为 `empty(col)`，并将 `col != ''` 或 `'' != col` 转换为 `notEmpty(col)`。

<div id="optimize_extract_common_expressions">
  ## optimize\_extract\_common\_expressions
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "25.1"},{"label": "1"},{"label": "通过从析取的合取项中提取公共表达式来优化 WHERE、PREWHERE、ON、HAVING 和 QUALIFY 表达式。"}]}, {"id": "row-2","items": [{"label": "24.12"},{"label": "0"},{"label": "引入此设置，用于通过从析取的合取项中提取公共表达式来优化 WHERE、PREWHERE、ON、HAVING 和 QUALIFY 表达式。"}]}]} />

允许在 WHERE、PREWHERE、ON、HAVING 和 QUALIFY 表达式中从析取项里提取公共表达式。像 `(A AND B) OR (A AND C)` 这样的逻辑表达式可以改写为 `A AND (B OR C)`，这可能有助于利用：

* 简单筛选表达式中的索引
* CROSS 到 INNER JOIN 的优化

<div id="optimize_functions_to_subcolumns">
  ## optimize\_functions\_to\_subcolumns
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "24.8"},{"label": "1"},{"label": "默认启用"}]}]} />

通过将某些函数优化为读取子列，启用或禁用相关优化。这可以减少需要读取的数据量。

可进行此类转换的函数包括：

* [length](/docs/zh/reference/functions/regular-functions/array-functions#length) 优化为读取 [size0](/docs/zh/reference/data-types/array#array-size) 子列。
* [empty](/docs/zh/reference/functions/regular-functions/array-functions#empty) 优化为读取 [size0](/docs/zh/reference/data-types/array#array-size) 子列。
* [notEmpty](/docs/zh/reference/functions/regular-functions/array-functions#notEmpty) 优化为读取 [size0](/docs/zh/reference/data-types/array#array-size) 子列。
* [isNull](/docs/zh/reference/functions/regular-functions/functions-for-nulls#isNull) 优化为读取 [null](/docs/zh/reference/data-types/nullable#finding-null) 子列。
* [isNotNull](/docs/zh/reference/functions/regular-functions/functions-for-nulls#isNotNull) 优化为读取 [null](/docs/zh/reference/data-types/nullable#finding-null) 子列。
* [count](/docs/zh/reference/functions/aggregate-functions/count) 优化为读取 [null](/docs/zh/reference/data-types/nullable#finding-null) 子列。
* [mapKeys](/docs/zh/reference/functions/regular-functions/tuple-map-functions#mapKeys) 优化为读取 [keys](/docs/zh/reference/data-types/map#reading-subcolumns-of-map) 子列。
* [mapValues](/docs/zh/reference/functions/regular-functions/tuple-map-functions#mapValues) 优化为读取 [values](/docs/zh/reference/data-types/map#reading-subcolumns-of-map) 子列。

Possible values:

* 0 — 禁用优化。
* 1 — 启用优化。

<div id="optimize_inverse_dictionary_lookup">
  ## optimize\_inverse\_dictionary\_lookup
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "25.12"},{"label": "1"},{"label": "新增设置"}]}]} />

通过更快地查找预先计算出的可能键值集合，避免重复进行反向字典查找。

<div id="optimize_multiif_to_if">
  ## optimize\_multiif\_to\_if
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

将仅包含一个条件的 `multiIf` 替换为 `if`。

<div id="optimize_normalize_count_variants">
  ## optimize\_normalize\_count\_variants
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "21.3"},{"label": "1"},{"label": "默认将语义上等价于 count() 的聚合函数重写为 count()"}]}]} />

将语义上等价于 count() 的聚合函数重写为 count()。

<div id="optimize_on_insert">
  ## optimize\_on\_insert
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "21.1"},{"label": "1"},{"label": "默认在 INSERT 时启用数据优化，以提供更好的用户体验"}]}]} />

启用或禁用在插入前对数据进行转换，其效果相当于已对该块执行了合并 (具体取决于表引擎) 。

可能的值：

* 0 — 禁用。
* 1 — 启用。

**示例**

启用与禁用的区别：

查询：

```sql theme={null}
SET optimize_on_insert = 1;

CREATE TABLE test1 (`FirstTable` UInt32) ENGINE = ReplacingMergeTree ORDER BY FirstTable;

INSERT INTO test1 SELECT number % 2 FROM numbers(5);

SELECT * FROM test1;

SET optimize_on_insert = 0;

CREATE TABLE test2 (`SecondTable` UInt32) ENGINE = ReplacingMergeTree ORDER BY SecondTable;

INSERT INTO test2 SELECT number % 2 FROM numbers(5);

SELECT * FROM test2;
```

结果：

```text theme={null}
┌─FirstTable─┐
│          0 │
│          1 │
└────────────┘

┌─SecondTable─┐
│           0 │
│           0 │
│           0 │
│           1 │
│           1 │
└─────────────┘
```

请注意，此设置项会影响 [materialized view](/docs/zh/reference/statements/create/view#materialized-view) 的行为。

<div id="optimize_prewhere_after_pushdown">
  ## optimize\_prewhere\_after\_pushdown
</div>

<SettingsInfoBlock type="Bool" default_value="0" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "26.6"},{"label": "0"},{"label": "启用第二轮 PREWHERE 提升的新设置，用于将后续优化（如通过 JOIN 的谓词下推、投影重写）在 MergeTree 读取步骤上方产生的过滤器合并到现有的 PREWHERE 链中。"}]}]} />

在后续查询计划优化可能已在 `MergeTree` 读取步骤上方
产生额外过滤器 (例如通过 `JOIN` 的谓词下推、
投影重写) 后，执行第二轮 `PREWHERE` 提升。若已存在 `PREWHERE`，新的
过滤器会通过 `AND` 合并到其中，而不是保留为单独的过滤器步骤。

<div id="optimize_qbit_distance_function_reads">
  ## optimize\_qbit\_distance\_function\_reads
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "25.10"},{"label": "1"},{"label": "新设置"}]}]} />

将 `QBit` 数据类型上的距离函数替换为等效函数，后者仅从存储中读取计算所需的列。

<div id="optimize_read_in_order">
  ## optimize\_read\_in\_order
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

启用 [SELECT](/docs/zh/reference/statements/select/index) 查询中的 [ORDER BY](/docs/zh/reference/statements/select/order-by#optimization-of-data-reading) 优化，以便从 [MergeTree](/docs/zh/reference/engines/table-engines/mergetree-family/mergetree) 表中读取数据。

可能的值：

* 0 — `ORDER BY` 优化已禁用。
* 1 — `ORDER BY` 优化已启用。

**另请参见**

* [ORDER BY 子句](/docs/zh/reference/statements/select/order-by#optimization-of-data-reading)

<div id="optimize_respect_aliases">
  ## optimize\_respect\_aliases
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

如果将其设置为 true，则会在 WHERE/GROUP BY/ORDER BY 中识别别名，这将有助于分区裁剪/次级索引/optimize\_aggregation\_in\_order/optimize\_read\_in\_order/optimize\_trivial\_count

<div id="optimize_sorting_by_input_stream_properties">
  ## optimize\_sorting\_by\_input\_stream\_properties
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

根据输入流的排序属性优化排序

<div id="optimize_substitute_columns">
  ## optimize\_substitute\_columns
</div>

<SettingsInfoBlock type="Bool" default_value="0" />

使用[约束](/docs/zh/reference/statements/create/table#constraints)来替换列。默认值为 `false`。

可选值：

* true, false

<div id="optimize_syntax_fuse_functions">
  ## optimize\_syntax\_fuse\_functions
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "26.3"},{"label": "1"},{"label": "该优化已达到生产可用状态"}]}]} />

启用将具有相同参数的聚合函数融合。它会将包含至少两个参数相同的 [sum](/docs/zh/reference/functions/aggregate-functions/sum)、[count](/docs/zh/reference/functions/aggregate-functions/count) 或 [avg](/docs/zh/reference/functions/aggregate-functions/avg) 聚合函数的查询重写为 [sumCount](/docs/zh/reference/functions/aggregate-functions/sumCount)。

可能的值：

* 0 — 不融合参数相同的函数。
* 1 — 融合参数相同的函数。

**示例**

查询：

```sql theme={null}
CREATE TABLE fuse_tbl(a Int8, b Int8) Engine = Log;
SET optimize_syntax_fuse_functions = 1;
EXPLAIN SYNTAX run_query_tree_passes = 1 SELECT sum(a), sum(b), count(b), avg(b) from fuse_tbl FORMAT TSV;
```

结果：

```text theme={null}
SELECT
    sum(__table1.a) AS `sum(a)`,
    tupleElement(sumCount(__table1.b), 1) AS `sum(b)`,
    tupleElement(sumCount(__table1.b), 2) AS `count(b)`,
    divide(tupleElement(sumCount(__table1.b), 1), toFloat64(tupleElement(sumCount(__table1.b), 2))) AS `avg(b)`
FROM default.fuse_tbl AS __table1
```

<div id="optimize_throw_if_noop">
  ## optimize\_throw\_if\_noop
</div>

<SettingsInfoBlock type="Bool" default_value="0" />

启用或禁用以下行为：如果 [OPTIMIZE](/docs/zh/reference/statements/optimize) 查询未执行合并，则抛出异常。

默认情况下，即使 `OPTIMIZE` 没有执行任何操作，也会成功返回。此设置可让您区分这些情况，并在异常消息中获取原因。

可能的值：

* 1 — 启用抛出异常。
* 0 — 禁用抛出异常。

<div id="optimize_time_filter_with_preimage">
  ## optimize\_time\_filter\_with\_preimage
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "24.2"},{"label": "1"},{"label": "通过将函数改写为无需转换的等效比较来优化 Date 和 日期时间 谓词（例如 toYear(col) = 2023 -> col >= '2023-01-01' AND col <= '2023-12-31'）"}]}]} />

通过将函数改写为无需转换的等效比较来优化 Date 和 日期时间 谓词 (例如 `toYear(col) = 2023 -> col >= '2023-01-01' AND col <= '2023-12-31'`)

<div id="optimize_truncate_order_by_after_group_by_keys">
  ## optimize\_truncate\_order\_by\_after\_group\_by\_keys
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "26.4"},{"label": "1"},{"label": "当 ORDER BY 前缀已覆盖所有 GROUP BY 键时，移除 ORDER BY 末尾的多余元素。"}]}]} />

当 ORDER BY 前缀已覆盖所有 GROUP BY 键时，移除 ORDER BY 末尾的多余元素。

<div id="optimize_uniq_to_count">
  ## optimize\_uniq\_to\_count
</div>

<SettingsInfoBlock type="Bool" default_value="1" />

如果子查询包含 distinct 或 GROUP BY 子句，则将 uniq 及其各种变体 (uniqUpTo 除外) 改写为 count。

<div id="optimize_using_constraints">
  ## optimize\_using\_constraints
</div>

<SettingsInfoBlock type="Bool" default_value="0" />

使用[约束](/docs/zh/reference/statements/create/table#constraints)进行查询优化。默认值为 `false`。

可能的值：

* true, false
