> ## 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_* 세션 설정

> optimize_* 생성 그룹에 속한 ClickHouse 세션 설정입니다.

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/ko/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/ko/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": "큰 상수는 스칼라로 대체하고 이름으로 hash를 사용합니다(크기는 이름 길이를 기준으로 추정됨)"}]}]} />

큰 상수는 스칼라로 대체하고 이름으로 hash를 사용합니다(크기는 이름 길이를 기준으로 추정됨).

가능한 값:

* 양의 정수 - 이름의 최대 길이,
* 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`) 접근을 지원하며, 기본값 인수가 상수 Tuple 또는 상수들로 이루어진 `tuple(...)`인 경우에는 `dictGetOrDefault`에도 적용됩니다.

<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" />

비용이 많이 드는 시작 서버(initiator server)에서의 집계를 피하여 `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/ko/reference/settings/session-settings/distributed#distributed_group_by_no_merge)
* [distributed\_push\_down\_limit](/docs/ko/reference/settings/session-settings/distributed#distributed_push_down_limit)
* [optimize\_skip\_unused\_shards](/docs/ko/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 = ''` 또는 `'' = col`과 같은 표현식은 `empty(col)`로, `col != ''` 또는 `'' != col`과 같은 표현식은 `notEmpty(col)`로 변환합니다.
이는 `col`이 `String` 또는 `FixedString` 타입인 경우에만 적용됩니다.

<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 표현식에서 AND 식들의 OR 결합으로부터 공통 표현식을 추출해 최적화합니다."}]}, {"id": "row-2","items": [{"label": "24.12"},{"label": "0"},{"label": "WHERE, PREWHERE, ON, HAVING 및 QUALIFY 표현식에서 AND 식들의 OR 결합으로부터 공통 표현식을 추출해 최적화하는 설정을 도입합니다."}]}]} />

WHERE, PREWHERE, ON, HAVING 및 QUALIFY 표현식의 OR 결합에서 공통 표현식을 추출할 수 있도록 허용합니다. `(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/ko/reference/functions/regular-functions/array-functions#length)를 [size0](/docs/ko/reference/data-types/array#array-size) 서브컬럼을 읽도록 변환합니다.
* [empty](/docs/ko/reference/functions/regular-functions/array-functions#empty)를 [size0](/docs/ko/reference/data-types/array#array-size) 서브컬럼을 읽도록 변환합니다.
* [notEmpty](/docs/ko/reference/functions/regular-functions/array-functions#notEmpty)를 [size0](/docs/ko/reference/data-types/array#array-size) 서브컬럼을 읽도록 변환합니다.
* [isNull](/docs/ko/reference/functions/regular-functions/functions-for-nulls#isNull)을 [null](/docs/ko/reference/data-types/nullable#finding-null) 서브컬럼을 읽도록 변환합니다.
* [isNotNull](/docs/ko/reference/functions/regular-functions/functions-for-nulls#isNotNull)을 [null](/docs/ko/reference/data-types/nullable#finding-null) 서브컬럼을 읽도록 변환합니다.
* [count](/docs/ko/reference/functions/aggregate-functions/count)를 [null](/docs/ko/reference/data-types/nullable#finding-null) 서브컬럼을 읽도록 변환합니다.
* [mapKeys](/docs/ko/reference/functions/regular-functions/tuple-map-functions#mapKeys)를 [keys](/docs/ko/reference/data-types/map#reading-subcolumns-of-map) 서브컬럼을 읽도록 변환합니다.
* [mapValues](/docs/ko/reference/functions/regular-functions/tuple-map-functions#mapValues)를 [values](/docs/ko/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/ko/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": "후속 최적화(예: `JOIN`을 통한 프레디케이트 pushdown, projection 재작성)로 `MergeTree` 읽기 단계 위에 추가된 필터를 기존 `PREWHERE` 체인에 병합할 수 있도록, 두 번째 `PREWHERE` 승격 패스를 활성화하는 새로운 설정입니다."}]}]} />

후속 쿼리 계획 최적화로 `MergeTree` 읽기 단계 위에 추가 필터가 배치될 수 있는 경우(예: `JOIN`을 통한 프레디케이트 pushdown, projection 재작성), 그 이후 두 번째 `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" />

[MergeTree](/docs/ko/reference/engines/table-engines/mergetree-family/mergetree) 테이블에서 데이터를 읽을 때 [SELECT](/docs/ko/reference/statements/select/index) 쿼리의 [ORDER BY](/docs/ko/reference/statements/select/order-by#optimization-of-data-reading) 최적화를 활성화합니다.

가능한 값:

* 0 — `ORDER BY` 최적화가 비활성화됩니다.
* 1 — `ORDER BY` 최적화가 활성화됩니다.

**관련 항목**

* [ORDER BY 절](/docs/ko/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/ko/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/ko/reference/functions/aggregate-functions/sum), [count](/docs/ko/reference/functions/aggregate-functions/count) 또는 [avg](/docs/ko/reference/functions/aggregate-functions/avg) 집계 함수가 2개 이상 포함된 쿼리를 [sumCount](/docs/ko/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/ko/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 및 DateTime 프레디케이트를 최적화합니다(예: toYear(col) = 2023 -> col >= '2023-01-01' AND col <= '2023-12-31')"}]}]} />

함수를 변환이 필요 없는 동등한 비교식으로 변환하여 Date 및 DateTime 프레디케이트를 최적화합니다(예: `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": "모든 GROUP BY 키가 ORDER BY 접두사에 포함되면 끝부분의 ORDER BY 원소를 제거합니다."}]}]} />

모든 GROUP BY 키가 ORDER 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/ko/reference/statements/create/table#constraints)을 사용합니다. 기본값은 `false`입니다.

가능한 값:

* true, false
