> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> `clickhouse-go` 客户端的完整逐项配置参考，涵盖连接级、上下文级和批次选项。

# Go 客户端配置参考

本页列出了 `clickhouse-go` v2.x 中所有可配置选项。若需查看包含代码示例的指南，请参阅[配置](/zh/integrations/language-clients/go/configuration)。

<Info>
  **版本标注**

  在 `clickhouse-go` v2.35.0 及更高版本中新增的选项，会在其说明旁标注 *(自 vX.Y.Z 起)*。没有 “Since” 标记的选项自 v2.0 起即已可用，并包含在所有受支持的版本中。
</Info>

<div id="how-options-are-set">
  ## 选项的设置方式
</div>

选项可在三个作用范围内设置：

| 作用范围 | 设置方式 | 生效时长 |
| - | - | - |
| **连接** | `clickhouse.Options` 结构体或 DSN 字符串 | 该连接上的所有查询 |
| **查询** | 带有 `WithXxx` 函数的 `clickhouse.Context()` | 单次查询执行 |
| **批次** | `PrepareBatch()` 选项函数 | 单次批次操作 |

当多个作用范围重叠时，范围越具体，优先级越高：**批次 > 查询 > 连接**。对于 `Settings`，查询级别的键会与连接级别的键合并；如果发生冲突，则以查询级别为准。

**通过 Options 结构体：**

```go theme={null}
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr:        []string{"localhost:9000"},
    Auth:        clickhouse.Auth{Database: "default", Username: "default", Password: ""},
    DialTimeout: 10 * time.Second,
    Compression: &clickhouse.Compression{Method: clickhouse.CompressionLZ4},
})
```

**通过 DSN 连接字符串：**

```go theme={null}
db, err := sql.Open("clickhouse", "clickhouse://user:pass@localhost:9000/default?dial_timeout=10s&compress=lz4")
```

**通过 Connector (使用 Options 结构体的 `database/sql`) ：**

```go theme={null}
db := sql.OpenDB(clickhouse.Connector(&clickhouse.Options{
    Addr:        []string{"localhost:9000"},
    Auth:        clickhouse.Auth{Database: "default", Username: "default"},
    DialTimeout: 10 * time.Second,
}))
// 创建后设置仅适用于 database/sql 的连接池参数
db.SetConnMaxIdleTime(5 * time.Minute)
```

**通过 Context (按查询) ：**

```go theme={null}
ctx := clickhouse.Context(context.Background(),
    clickhouse.WithQueryID("my-query-123"),
    clickhouse.WithSettings(clickhouse.Settings{"max_execution_time": 60}),
)
rows, err := conn.Query(ctx, "SELECT ...")
```

***

<div id="connection-options">
  ## 连接选项
</div>

<div id="protocol-and-connection">
  ### 协议和连接
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | 描述 | 最佳实践 | 配置错误时 |
| - | - | - | - | - | - | - |
| `Protocol` | `Protocol` (int) | `Native` | 协议方案：`clickhouse://`=Native，`http://`=HTTP | 通信协议：`Native` (0) 用于 TCP，`HTTP` (1) 用于 HTTP | `Native` 的性能通常高约 30%，应优先使用。若需要支持 proxy、穿过 firewall (80/443 端口) ，或使用仅 HTTP 支持的压缩 (`gzip`/`br`) ，请使用 `HTTP`。参见 [TCP 与 HTTP](/zh/integrations/language-clients/go/configuration#tcp-vs-http)。 | HTTP 协议方案配 Native 端口 (9000) ：connection refused。`Native` 被 firewall 阻止：发生 timeout。 |
| `Addr` | `[]string` | `["localhost:9000"]` (Native) `["localhost:8123"]` (HTTP) | URL 中以逗号分隔的主机 | 用于连接和故障转移的 `"host:port"` 地址列表 | 在 production 环境中指定多个地址以实现高可用。正确端口：9000 (`Native`)、8123 (`HTTP`)、9440 (`Native`+`TLS`)、8443 (`HTTP`+`TLS`)。 | 单个地址：无故障转移。端口错误：`"connection refused"`。空值/nil：默认使用 localhost，在分布式部署中会失败。 |
| `ConnOpenStrategy` | `ConnOpenStrategy` (uint8) | `ConnOpenInOrder` (0) | `connection_open_strategy` (`in_order`, `round_robin`, `random`) | 从 `Addr` 中选择 server 的策略。`InOrder` (0)=故障转移，`RoundRobin` (1)=负载均衡，`Random` (2)=随机。 | 主备场景使用 `InOrder`。双活/K8s 场景使用 `RoundRobin`。为避免惊群效应，可使用 `Random`。 | 在双活场景中使用 `InOrder`：第一台 server 会承受全部负载，其他 server 处于 idle。所有策略在失败时都会尝试所有 server——只影响*优先*尝试哪个。 |

***

<div id="authentication">
  ### 身份验证
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | 说明 | 最佳实践 | 配置错误时 |
| - | - | - | - | - | - | - |
| `Auth.Username` | `string` | `"default"` | `username` 或 URL 用户部分 | 用于 ClickHouse 身份验证的用户名 | 生产环境中绝不要使用 `default`。请创建权限最小化的专用用户。 | 用户名错误：`"Code: 516. DB::Exception: Authentication failed"`。空字符串：会静默使用 `"default"`。 |
| `Auth.Password` | `string` | `""` | `password` 或 URL 密码部分 | 用于 ClickHouse 身份验证的密码 | 生产环境中请使用环境变量或 secret 管理器。在 DSN 中对特殊字符进行 URL 编码。 | 密码错误：`"Code: 516. DB::Exception: Authentication failed"`。特殊字符未进行 URL 编码：会出现解析错误。 |
| `Auth.Database` | `string` | `""` (server 默认值) | `database` 或 URL 路径 (`/mydb`) | connection 的默认数据库 | 始终显式指定。生产环境中请为每个应用使用专用数据库。 | 不存在：`"Code: 81. DB::Exception: Database xyz doesn't exist"`。在多租户设置中留空：查询会落到错误的数据库。 |
| `GetJWT` | `func(ctx) (string, error)` | `nil` | (仅可通过程序方式设置) | 返回用于 ClickHouse Cloud 身份验证的 JWT 的回调。可通过 `WithJWT(token)` 为每个查询覆盖。* (自 v2.35.0 起) *  | 实现标记缓存/刷新——它会在每次 connection/request 时调用。 | 标记过期：会出现身份验证错误。阻塞式回调：会导致超时。JWT 的优先级高于用户名/密码。需要 TLS——否则会静默回退到用户名/密码。 |

```go theme={null}
GetJWT: func(ctx context.Context) (string, error) {
    return getTokenFromVault(ctx)
}
```

***

<div id="timeouts">
  ### 超时
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | 说明 | 最佳实践 | 配置不当时 |
| - | - | - | - | - | - | - |
| `DialTimeout` | `time.Duration` | `30s` | `dial_timeout` | 建立新连接的最长等待时间。达到 `MaxOpenConns` 时，它也控制从连接池获取连接的等待时间。 | LAN 环境下为 5-10 秒，WAN/云环境下为 15-30 秒；如果连接到已休眠的 ClickHouse Cloud 服务，则为 1-2 分钟。切勿低于 1 秒。 | 过短：拥塞期间出现 `"clickhouse: acquire conn timeout"`，或在已休眠的 Cloud 服务完成唤醒前连接失败。过长 (> 60 秒)：故障期间应用会一直挂起。 |
| `ReadTimeout` | `time.Duration` | `5m` (300s) | `read_timeout` | 单次 read 调用等待服务器响应的最长时间。按每个块生效，而非整个查询。`Context deadline` 优先生效。 | 较短的交互式查询设为 10-30 秒；较长的分析型查询设为 5-30 分钟。 | 过短：查询中途出现 `"i/o timeout"` 或 `"read: connection reset by peer"`；服务器仍会继续执行。过长：无法及时检测失效连接。 |

<Note title="ClickHouse Cloud 休眠服务">
  已空闲的 ClickHouse Cloud 服务会被暂停，并在收到第一个传入连接时唤醒。唤醒通常需要几十秒，在此期间拨号会阻塞。如果 `DialTimeout` 低于唤醒时间，则空闲一段时间后的第一次查询会因拨号超时而失败，而不是正常执行。

  对于可能是第一个访问已休眠服务的 client，请将 `DialTimeout` 设为 `1m`–`2m`。代价是在真实故障期间检测失败会更慢——拨号会一直阻塞到完整超时时间后才报错——因此更建议只对首次连接应用较高的超时，或在单个查询上使用 Context deadline 来限制端到端耗时。
</Note>

***

<div id="connection-pool">
  ### 连接池
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | API | 说明 | 最佳实践 | 配置不当时 |
| - | - | - | - | - | - | - | - |
| `MaxIdleConns` | `int` | `5` | `max_idle_conns` | 两者 | 连接池中空闲 (未使用但仍保持存活) 的最大连接数 | 设为预期并发查询数的 50-80%。低：2-5，中：10-20，高：20-50。 | 过低：连接频繁创建和销毁，延迟升高。过高：浪费内存。会自动受 `MaxOpenConns` 限制。 |
| `MaxOpenConns` | `int` | `MaxIdleConns + 5` (默认：10) | `max_open_conns` | 两者 | 最大连接总数 (空闲 + 活跃) | 低：10-20，中：20-50，高：50-100。公式：并发查询数 + 突发量 + 缓冲。监控：`SELECT * FROM system.metrics WHERE metric='TCPConnection'`。 | 过低：`"clickhouse: acquire conn timeout"`。过高：服务器报错 `"Too many connections"`，并可能超出 FD 限制。ClickHouse 默认 `max_connections`：1024 (共享) 。 |
| `ConnMaxLifetime` | `time.Duration` | `1h` | `conn_max_lifetime` | 两者 | 连接可复用的最长时间。在归还到连接池时检查。 | 稳定环境建议 1-5h。K8s/滚动部署建议 5-15m。切勿设为无限。 | 过短 (\< 1m) ：频繁创建和销毁连接，延迟升高。过长/无限：连接陈旧、无法感知 DNS 变更，流量也不会重新均衡。 |
| `ConnMaxIdleTime` | `time.Duration` | `0` (无) | — | 仅 `database/sql` | 连接在关闭前允许保持*空闲*的最长时间。不在 `Options` struct 中——需通过 `db.SetConnMaxIdleTime()` 设置。 | 对于 K8s/突发型 workload，建议设为 5-10m，以便在流量峰值后回收空闲连接。 | 未设置：空闲连接会一直保留到 `ConnMaxLifetime`。过短 (\< 30s) ：即使在正常空档期间也会重建连接。 |

<Info>
  **仅适用于 database/sql**

  `ConnMaxIdleTime` 是 Go 标准 `database/sql` 连接池设置。它不在 `clickhouse.Options` struct 中，也不能通过 `clickhouse.Open()` 设置。请在 `OpenDB()` 之后设置：

  ```go theme={null}
  db := clickhouse.OpenDB(&clickhouse.Options{...})
  db.SetConnMaxIdleTime(5 * time.Minute)
  ```
</Info>

用法详见 [连接池](/zh/integrations/language-clients/go/configuration#connection-pooling)。

***

<div id="sql-db-settings">
  ### 标准 database/sql 连接池设置
</div>

使用 `clickhouse.OpenDB()` 或 `sql.Open("clickhouse", dsn)` 时，返回的 `*sql.DB` 支持 Go 的标准连接池方法。`OpenDB()` 会自动应用 `Options` 中的前三项：

| 方法 | 对应的 Options 配置 | 说明 |
| - | - | - |
| `db.SetMaxIdleConns(n)` | `MaxIdleConns` | 由 `OpenDB()` 自动应用 |
| `db.SetMaxOpenConns(n)` | `MaxOpenConns` | 由 `OpenDB()` 自动应用 |
| `db.SetConnMaxLifetime(d)` | `ConnMaxLifetime` | 由 `OpenDB()` 自动应用 |
| `db.SetConnMaxIdleTime(d)` | *None* | 必须在创建后手动设置 |

<Info>
  **ClickHouse API (clickhouse.Open)**

  `clickhouse.Open()` 返回的连接不支持这些方法。ClickHouse API 会直接使用 `Options` 结构体中的字段，在内部管理自己的连接池。
</Info>

***

<div id="compression">
  ### 压缩
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | 描述 | 最佳实践 | 配置不当时 |
| - | - | - | - | - | - | - |
| `Compression.Method` | `CompressionMethod` (byte) | None | `compress` (`lz4`, `zstd`, `lz4hc`, `gzip`, `deflate`, `br`，或使用 `true` 表示 LZ4) | 用于数据传输的压缩算法。请参见下方的协议支持矩阵。 | LAN：None 或 LZ4。WAN：ZSTD 或 LZ4。CPU 资源受限：LZ4。追求最高压缩率：ZSTD (Native) 或 Brotli (HTTP) 。对于小于 1 MB 的插入可跳过压缩。 | 在 Native 上使用 GZIP/Brotli：握手失败。在 HTTP 上使用 LZ4HC：报错或静默回退。慢速网络上不使用压缩：插入速度会慢 10-100 倍。 |
| `Compression.Level` | `int` | `3` | `compress_level` | 算法对应的压缩强度。GZIP/Deflate：-2 到 9。Brotli：0 到 11。LZ4/ZSTD：会被忽略。 | GZIP 的平衡设置：3-6。Brotli 的平衡设置：4-6。 | 级别过高：CPU 开销极大、收益很小。对 LZ4/ZSTD 设为非零：会被静默忽略。未启用压缩时设置 Level：无效果。 |
| `MaxCompressionBuffer` | `int` (bytes) | `10485760` (10 MiB) | `max_compression_buffer` | 刷写前允许使用的最大压缩缓冲区大小。每个连接都有自己的缓冲区。 | 默认 10 MiB 通常就足够。对于宽行可设为 20-50 MiB。总内存 = buffer x `MaxOpenConns`。 | 过小 (\< 1 MiB) ：频繁刷写，效率较低。过大 (> 100 MiB)：连接较多时可能导致 OOM。 |

**按协议划分的压缩方法支持情况：**

| 方法 | Native | HTTP |
| - | - | - |
| `CompressionLZ4` | 是 | 是 |
| `CompressionLZ4HC` | 是 | 否 |
| `CompressionZSTD` | 是 | 是 |
| `CompressionGZIP` | 否 | 是 |
| `CompressionDeflate` | 否 | 是 |
| `CompressionBrotli` | 否 | 是 |

***

<div id="tls">
  ### TLS
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | 描述 | 最佳实践 | 配置错误时 |
| - | - | - | - | - | - | - |
| `TLS` | `*tls.Config` | `nil` (明文) | `secure=true`, `skip_verify=true` | TLS/SSL 配置。非 `nil` 时启用 TLS。端口：Native 9000/9440，HTTP 8123/8443。 | 在生产环境和 ClickHouse Cloud 中务必启用 (必需) 。在生产环境中将 `InsecureSkipVerify` 设为 `false`。可通过 `RootCAs` 添加自定义 CA。 | 端口错误：`"connection reset by peer"`。在生产环境中使用 `skip_verify=true`：存在遭受 MITM 攻击的风险。证书已过期：`"x509: certificate has expired"`。主机名错误：`"x509: certificate is valid for X, not Y"`。CA 不受信任：`"x509: certificate signed by unknown authority"`。如果 HTTP DSN 使用了 `secure=true`：请改用 `https://` 协议。 |

代码示例请参见 [TLS](/zh/integrations/language-clients/go/configuration#using-tls)。

***

<div id="logging">
  ### 日志
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | 描述 | 最佳实践 | 配置错误时 |
| - | - | - | - | - | - | - |
| `Logger` | `*slog.Logger` | `nil` (不记录日志) | — | 通过 Go 的 `log/slog` 提供结构化日志记录器。优先级：`Debug`+`Debugf` > `Logger` > 空操作。* (自 v2.43.0 起) *  | 在生产环境中使用配备 JSON 处理器的 `slog`。使用 `logger.With(...)` 添加应用上下文。 | — |
| `Debug` (deprecated) | `bool` | `false` | `debug` | 旧版调试开关。请改用 `Logger`。如果未设置 `Debugf`，日志将输出到 `stdout`。 | — | 在生产环境中启用：会带来性能开销、产生冗长日志，并可能在输出中包含敏感数据。 |
| `Debugf` (deprecated) | `func(string, ...any)` | `nil` | — | 自定义调试日志函数。请改用 `Logger`。要求设置 `Debug: true`。 | — | — |

```go theme={null}
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
conn, err := clickhouse.Open(&clickhouse.Options{
    Logger: logger,
    // ...
})
```

完整示例请参见[日志](/zh/integrations/language-clients/go/configuration#logging)。

***

<div id="buffers-and-memory">
  ### 缓冲区与内存
</div>

| 选项 | Type | 默认值 | DSN 参数 | 按查询 | 说明 | 最佳实践 | 配置不当时 |
| - | - | - | - | - | - | - | - |
| `BlockBufferSize` | `uint8` | `2` | `block_buffer_size` | 是 (`WithBlockBufferSize`) | 读取结果时要缓冲的已解码块数。支持并发读取与解码。 | 默认值 2 即可。对于大型流式结果，可设为 5-10。内存 = 缓冲区 × 块大小 × 并发查询数。 | 过小 (1) ：会阻塞块读取器，延迟更高。过大 (> 50) ：内存占用高，收益递减。 |
| `FreeBufOnConnRelease` | `bool` | `false` | — | 否 | 每次查询后释放连接的内存缓冲区，而不是复用。 | 查询频率高时使用 `false`。在内存受限的容器中，或不频繁处理大批次时，使用 `true`。 | `false` + 内存受限：缓冲区会累积 (内存 = 缓冲区 × 空闲连接数) 。`true` + 高速率：GC 压力增大，CPU 开销增加。 |

***

<div id="http-specific">
  ### HTTP 专用
</div>

<Warning>
  **在 Native 协议下会被静默忽略**

  这些选项仅影响 `Protocol: clickhouse.HTTP`。使用 Native 协议时，它们会被静默忽略，并且不会产生任何错误或警告。
</Warning>

| 选项 | 类型 | 默认值 | DSN 参数 | 说明 | 最佳实践 | 配置错误时 |
| - | - | - | - | - | - | - |
| `HttpHeaders` | `map[string]string` | `nil` | — | 为每个请求附加额外的 HTTP 请求头 | 用于 tracing (`X-Request-ID`) 或认证代理请求头。尽量保持最少。 | 覆盖内部请求头 (`Content-Type`、`Authorization`) ：行为不可预测。 |
| `HttpUrlPath` | `string` | `""` | `http_path` | 追加到请求上的 URL 路径。会自动添加前导 `/`。 | 在使用基于路径路由的 reverse proxy 时使用。 | 路径错误：代理/LB 返回 HTTP 404。 |
| `HttpMaxConnsPerHost` | `int` | `0` (unlimited) | — | 传输层每个主机的 TCP 连接数 (`http.Transport.MaxConnsPerHost`) 。 | 对大多数应用保留为 0。仅当 server 有严格的连接数限制时再设置。 | 值过低 (例如 `MaxOpenConns`=50 时设为 10) ：会造成传输层瓶颈，即使 server 负载较低，queries 仍会变慢。 |
| `HTTPProxyURL` | `*url.URL` | `nil` (uses env vars) | `http_proxy` (URL-encoded) | 用于转发请求的 HTTP proxy | 如果需要 proxy，请显式设置。它会覆盖 `HTTP_PROXY`/`HTTPS_PROXY` 环境变量。 | 地址错误：`"dial tcp: lookup proxy: no such host"`。proxy 需要认证：HTTP 407。 |
| `TransportFunc` | `func(*http.Transport) (http.RoundTripper, error)` | `nil` | — | 自定义 HTTP transport 工厂。接收默认 transport 以便进行包装。*(自 v2.41.0 起)* | 用于可观测性中间件。不要覆盖 `Proxy`、`DialContext`、`TLSClientConfig`。 | 返回 `nil`：panic。覆盖客户端字段：TLS/proxy 会被静默忽略。阻塞式 RoundTripper：deadlocks。 |

<Info>
  **双层 HTTP 连接池**

  使用 HTTP 时，存在两个连接池：

  * **第 1 层 (应用层) ：** `MaxIdleConns` / `MaxOpenConns` -- 控制 `httpConnect` 对象
  * **第 2 层 (传输层) ：** `HttpMaxConnsPerHost` -- 控制底层 TCP 连接

  Native 协议采用简单的 1:1 映射，并会忽略 `HttpMaxConnsPerHost`。
</Info>

```go theme={null}
TransportFunc: func(t *http.Transport) (http.RoundTripper, error) {
    return &loggingRoundTripper{transport: t}, nil
}
```

***

<div id="advanced-connection">
  ### 高级连接
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | 描述 | 最佳实践 | 配置不当时 |
| - | - | - | - | - | - | - |
| `DialContext` | `func(ctx, addr) (net.Conn, error)` | `nil` (标准拨号器) | — | 用于 TCP 连接的自定义拨号函数。兼容 Native 和 HTTP。 | 在 99% 的情况下保持为 `nil`。可用于 Unix 套接字、SOCKS 代理和自定义 DNS。 | 不遵循上下文：会导致挂起和资源泄漏。设置了 `TLS` 时：自定义拨号器必须自行处理 TLS。`net.Conn` 无效：会导致崩溃。 |
| `DialStrategy` | `func(ctx, connID, options, dial) (DialResult, error)` | `DefaultDialStrategy` | — | 自定义服务器选择和连接策略。会覆盖 `ConnOpenStrategy`。 | 在 99.9% 的情况下使用默认值。仅在需要地理感知路由、加权选择或健康检查时自定义。 | 未尝试所有服务器：即使有健康服务器可用也会失败。内部执行高开销操作：会在每次建立连接时阻塞连接池获取。 |

***

<div id="client-information">
  ### 客户端信息
</div>

| Option | Type | Default | DSN param | Per-query | Description | Best practice | When misconfigured |
| - | - | - | - | - | - | - | - |
| `ClientInfo` | `ClientInfo` struct | 自动：`clickhouse-go` 版本 + Go 运行时环境 | `client_info_product=myapp/1.0` | 是 (`WithClientInfo`，追加) | 发送给 ClickHouse 的应用标识信息。包含 `Products` (`[]struct{Name,Version}`) 和 `Comment` (`[]string`) 。可在 `system.query_log` 中看到。 | 始终设置应用名称和版本。查询归属示例：`SELECT client_name FROM system.query_log WHERE client_name LIKE '%myapp%'` | 未设置：在多服务环境中，无法识别是哪个服务发起了查询。 |

```go theme={null}
ClientInfo: clickhouse.ClientInfo{
    Products: []struct{ Name, Version string }{
        {Name: "my-service", Version: "1.0.0"},
    },
}
// 显示为：clickhouse-go/2.x my-service/1.0.0 (lv:go/1.23; os:linux)
```

***

<div id="server-settings">
  ### ClickHouse 服务器设置
</div>

| 选项 | 类型 | 默认值 | DSN 参数 | 是否支持按查询设置 | 说明 | 最佳实践 | 配置错误时 |
| - | - | - | - | - | - | - | - |
| `Settings` | `map[string]any` | `nil` | 任何未识别的参数 (例如 `?max_execution_time=60`) | 是 (`WithSettings`，冲突时以 context 为准) | 应用于每个查询的 ClickHouse server settings。DSN 转换：`"true"`→`1`，`"false"`→`0`，数值→`int`。 | 在连接级别设置通用限制，再通过 context 按查询覆盖。 | 拼写错误：可能被静默忽略，也可能因版本不同而报错。类型错误：`"Cannot parse string 'abc' as Int64"`。`max_execution_time=0` 且未设置 deadline：查询会一直运行。 |
| `CustomSetting` | `CustomSetting{Value string}` | — | — | 是 (通过 `WithSettings`) | 将某项设置标记为 "自定义" (非重要) 以用于 native protocol。即使服务器无法识别，也不会报错。HTTP 默认将所有设置都视为自定义。 | 用于 Experimental 或特定版本的设置。 | 将重要设置标记为自定义：如果不受支持，会被静默忽略。 |

**常见设置：**

| 设置 | 类型 | 说明 |
| - | - | - |
| `max_execution_time` | int | 查询超时时间 (秒) |
| `max_memory_usage` | int | 每个查询的内存限制 (字节) |
| `max_block_size` | int | 处理用块大小 |
| `readonly` | int | 1 = 只读，2 = 只读 + 可改设置 |

```go theme={null}
Settings: clickhouse.Settings{
    "max_execution_time":  60,                                        // 重要 -- 未知时报错
    "my_custom_setting":   clickhouse.CustomSetting{Value: "value"},  // 自定义 -- 未知时忽略
}
```

***

<div id="context-options">
  ## Context 级别查询选项
</div>

使用 `clickhouse.Context()` 为每个查询单独设置：

```go theme={null}
ctx := clickhouse.Context(context.Background(),
    clickhouse.WithQueryID("my-query"),
    clickhouse.WithSettings(clickhouse.Settings{"max_execution_time": 60}),
)
```

<Info>
  **Context 截止时间的行为**

  如果 Context 的截止时间 > 1 秒，`max_execution_time` 会自动设为 `seconds_remaining + 5`。这会覆盖任何手动设置的值。
</Info>

| 选项 | 类型 | 默认值 | 协议 | 描述 | 最佳实践 | 配置不当时 |
| - | - | - | - | - | - | - |
| `WithQueryID` | `string` | 自动生成 | 两者均支持 | 自定义查询 ID。可在 `system.query_log` 和 `system.processes` 中看到。 | 使用 UUID。便于执行 `KILL QUERY WHERE query_id='...'`。 | 重复的 ID：会导致 `system.query_log` 中出现混淆。 |
| `WithQuotaKey` | `string` | `""` | 两者均支持 | 用于多租户资源限制的 QUOTA 键。需要服务器端 QUOTA 配置。 | 用于按客户或按用户设置限制。 | 未配置 Quota：会被静默忽略。 |
| `WithJWT` | `string` | `""` | 仅支持 HTTPS | ClickHouse Cloud 的单次查询 JWT 覆盖设置。*(自 v2.35.0 起)* | 适用于多租户代理中的单请求认证。 | 未启用 TLS：将被忽略，并回退到连接认证。已过期：`"Token has expired"`。 |
| `WithSettings` | `Settings` | 继承连接设置 | 两者皆可 | 按查询设置的服务器级配置。会与 connection 级 Settings 合并；发生冲突时，以上下文为准。 | 按查询类型覆盖 `max_execution_time` 或 `max_rows_to_read`。 | 与连接级 `Settings` 相同。 |
| `WithParameters` | `参数` (`map[string]string`) | `nil` | 两者皆可 | 服务器端参数化查询的参数值。查询语法：`{param_name:Type}`。 | 为防止 SQL 注入，请使用此方式，而不要进行字符串拼接。 | 参数缺失：`"Substitution {param_name:Type} isn't set"`。类型不匹配：`"Cannot parse string 'abc' as UInt64"`。 |
| `WithAsync` | `bool` (wait) | 同步 | 两者 | 异步 insert 模式。设置 `async_insert=1`。`wait=true` 时还会设置 `wait_for_async_insert=1`。需要 ClickHouse 21.11+。*(自 v2.41.0 起；取代旧版 `WithStdAsync`。)* | 用于高吞吐量插入。 | `wait=false`：错误可能会异步出现——请检查 `system.asynchronous_insert_log`。与 SELECT 一起使用时：会被忽略。旧 server：`"Unknown setting async_insert"`。 |
| `WithLogs` | `func(*Log)` | `nil` | 仅支持 Native | 查询执行期间的服务器日志条目回调。 | 保持轻量快速——否则会阻塞执行。耗时较重的处理请使用 goroutine。 | 在 HTTP 上：不会被调用，且不会有任何提示。 |
| `WithProgress` | `func(*Progress)` | `nil` | 仅限原生协议 | 查询进度更新 (已处理的行数/字节数) 。 | 务必保持处理快速——否则会阻塞执行。 | 在 HTTP 上：不会被调用，且不会有任何提示。 |
| `WithProfileInfo` | `func(*ProfileInfo)` | `nil` | 仅适用于 Native | 查询执行统计信息回调。 | 务必保持轻量——否则会阻塞执行。 | 在 HTTP 上：不会被调用，且不会有任何提示。 |
| `WithProfileEvents` | `func([]ProfileEvent)` | `nil` | 仅适用于 Native | 性能计数器的回调函数。 | 务必尽快返回——否则会阻塞执行。 | 在 HTTP 下：永远不会被调用，且不会有任何提示。 |
| `WithoutProfileEvents` | — | 发送事件 | 仅原生协议 | 禁用 profile events。适用于 ≥ 25.11 服务器的性能优化。*(自 v2.44.0 起)* | 在不需要 profile events 时使用。 | 在较旧的 server 上：会因设置未知而报错。 |
| `WithExternalTable` | `...*ext.Table` | `nil` | 两者都支持 | 将临时查找表附加到查询中。数据按每次查询传输。 | 将表控制在 \< 10 MB 以内。原生协议比 HTTP (multipart) 更高效。 | 大表：每次查询的网络开销都较高。 |
| `WithUserLocation` | `*time.Location` | 服务器时区 | 两者均可 | 覆盖 DateTime 解析所用的时区。 | 当客户端与服务端时区不一致时，应显式设置。 | 时区错误：DateTime 值会在无提示的情况下偏差数小时，并可能导致数据损坏。 |
| `WithColumnNamesAndTypes` | `[]ColumnNameAndType` | `nil` (执行 DESCRIBE) | 仅限 HTTP | 在 HTTP 插入时，通过预先提供列信息，跳过 `DESCRIBE TABLE` 往返请求。 *(自 v2.37.0 起)* | 在 schema 已知且稳定时使用。 | 类型不匹配：`"Cannot convert String to UInt64"`。迁移后发生 schema drift：列信息已过时。 |
| `WithBlockBufferSize` | `uint8` | connection 级别 (2) | 两者皆可 | 为单个查询覆盖连接级别的 `BlockBufferSize`。 | 对于特定查询返回的大型结果集，可增大该值。 | — |
| `WithClientInfo` | `ClientInfo` | 连接级别 | 两者均支持 | 为单次查询附加额外的客户端信息。不会替换，只会追加。*(自 v2.42.0 起)* | 为每个请求添加上下文 (例如端点名称) 。 | — |
| `WithSpan` | `trace.SpanContext` | 为空 | 仅限 Native 协议 | 用于分布式链路追踪的 OpenTelemetry span 上下文。 | 参阅 [OpenTelemetry](/zh/integrations/language-clients/go/clickhouse-api#open-telemetry)。 | — |

```go theme={null}
ctx := clickhouse.Context(ctx,
    clickhouse.WithQueryID("query-123"),
    clickhouse.WithParameters(clickhouse.Parameters{
        "user_id": "12345",
    }),
    clickhouse.WithProgress(func(p *clickhouse.Progress) {
        log.Printf("Progress: %d rows, %d bytes", p.Rows, p.Bytes)
    }),
)
rows, err := conn.Query(ctx, "SELECT * FROM users WHERE id = {user_id:String}")
```

***

<div id="batch-options">
  ## 批次选项
</div>

传递给 `PrepareBatch()`。导入：`github.com/ClickHouse/clickhouse-go/v2/lib/driver`。

| Option | Default | Description | Best practice | When misconfigured |
| - | - | - | - | - |
| `WithReleaseConnection` | 连接会一直持有到 `Send()` | 在 `PrepareBatch()` 后立即将连接释放回连接池。在 `Send()`/`Flush()` 时重新获取。 | 对于长时间存在的批次 (数分钟/数小时) ，建议使用此选项以防止连接池耗尽。 | 长批次未使用此选项：如果活跃连接很多，可能会出现 `"acquire conn timeout"`。 |
| `WithCloseOnFlush` | 批次保持打开状态 | 调用 `Flush()` 时自动关闭批次。 | 适用于一次性批次。可省去显式调用 `Close()`。 | 与多次 `Flush()` 调用一起使用时：第一次 flush 会关闭批次，后续操作会失败。 |

```go theme={null}
batch, err := conn.PrepareBatch(ctx, "INSERT INTO table",
    driver.WithReleaseConnection(),
    driver.WithCloseOnFlush(),
)
```

***

<div id="quick-reference-tables">
  ## 速查表
</div>

<div id="pool-sizing">
  ### 连接池大小建议
</div>

| 应用类型 | MaxIdleConns | MaxOpenConns | ConnMaxLifetime |
| - | - | - | - |
| 低流量 Web 应用 | 5 | 10 | 1h |
| 中等流量 API | 20 | 50 | 30m |
| 高流量服务 | 50 | 100 | 15m |
| 后台批次作业 | 10 | 20 | 2h |
| Kubernetes 部署 | 10 | 20 | 10m |
| 无服务器 (Lambda) | 1 | 5 | 5m |

<div id="timeout-recommendations">
  ### 超时建议
</div>

| 环境 | DialTimeout | ReadTimeout |
| - | - | - |
| 本地 / 局域网 | 5s | 30s |
| Cloud，同一区域 | 10s | 2m |
| Cloud，跨区域 | 30s | 5m |
| OLAP 工作负载 | 10s | 30m |
| 实时 / OLTP | 5s | 10s |

<div id="dsn-parameters">
  ### DSN 参数速查
</div>

| DSN 参数 | Options 字段 | 示例 |
| - | - | - |
| `username` | `Auth.Username` | `?username=admin` |
| `password` | `Auth.Password` | `?password=secret` |
| `database` | `Auth.Database` | `?database=mydb` 或路径中的 `/mydb` |
| `dial_timeout` | `DialTimeout` | `?dial_timeout=10s` |
| `read_timeout` | `ReadTimeout` | `?read_timeout=5m` |
| `max_open_conns` | `MaxOpenConns` | `?max_open_conns=50` |
| `max_idle_conns` | `MaxIdleConns` | `?max_idle_conns=20` |
| `conn_max_lifetime` | `ConnMaxLifetime` | `?conn_max_lifetime=30m` |
| `connection_open_strategy` | `ConnOpenStrategy` | `?connection_open_strategy=round_robin` |
| `block_buffer_size` | `BlockBufferSize` | `?block_buffer_size=10` |
| `compress` | `Compression.Method` | `?compress=lz4` |
| `compress_level` | `Compression.Level` | `?compress_level=6` |
| `max_compression_buffer` | `MaxCompressionBuffer` | `?max_compression_buffer=20971520` |
| `secure` | `TLS` | `?secure=true` |
| `skip_verify` | `TLS.InsecureSkipVerify` | `?skip_verify=true` |
| `debug` | `Debug` | `?debug=true` |
| `client_info_product` | `ClientInfo.Products` | `?client_info_product=myapp/1.0` |
| `http_proxy` | `HTTPProxyURL` | `?http_proxy=http%3A%2F%2Fproxy%3A8080` |
| `http_path` | `HttpUrlPath` | `?http_path=/clickhouse` |
| *(其他任意参数)* | `Settings[key]` | `?max_execution_time=60` |

***

<div id="troubleshooting">
  ## 故障排查
</div>

<div id="acquire-conn-timeout">
  ### 连接池耗尽："acquire conn timeout"
</div>

\*\*原因：\*\*连接池已耗尽——所有 `MaxOpenConns` 连接都在使用中，且在 `DialTimeout` 期限内没有连接可用。

**解决方法**

请按顺序尝试以下步骤，并在调整参数前先排查根本原因：

1. 检查是否有长时间运行并占用连接的查询：`SELECT query_id, elapsed FROM system.processes ORDER BY elapsed DESC`。如果有，先处理这些慢查询。
2. 如果你运行的是长生命周期的批次 (从 `PrepareBatch()` 到 `Send()` 之间相隔数分钟或数小时) ，请使用 `WithReleaseConnection()`，以便在批次保持打开期间将连接归还到连接池。
3. 增加 `MaxOpenConns`，使其与实际观测到的并发度相匹配。
4. 仅当预期会出现突发流量，且等待获取连接确实是瓶颈时，才增加 `DialTimeout`。

<div id="io-timeout">
  ### 读取超时和连接重置错误
</div>

**原因：** 等待服务器响应时超过了 `ReadTimeout`，或者连接被服务器/网络关闭。

**解决方法：**

* 对长时间运行的查询增大 `ReadTimeout`
* 使用 Context deadline 控制每个查询的超时时间
* 检查 ClickHouse 服务端的 `max_execution_time` 限制

<div id="auth-failed">
  ### "Code: 516. 身份验证失败"
</div>

**原因：** 用户名或密码错误，或者用户不存在。

**解决方法：**

* 对照 `system.users` 表核实凭据
* 检查 DSN 密码中的特殊字符是否存在 URL 编码问题
* 确认该用户有权访问指定数据库

<div id="tls-errors">
  ### TLS 证书错误
</div>

| 错误 | 原因 | 解决方法 |
| - | - | - |
| `x509: certificate has expired` | 服务器证书已过期 | 更新服务器证书 |
| `x509: certificate is valid for X, not Y` | 主机名不匹配 | 使用正确的主机名，或将其添加到 SANs |
| `x509: certificate signed by unknown authority` | CA 不受信任 | 将 CA 添加到 `tls.Config.RootCAs` |
| `connection reset by peer` | TLS/端口不匹配 | TLS 请使用 9440 (Native) 或 8443 (HTTP) 端口 |

<div id="memory-growth">
  ### 内存逐渐增长
</div>

**原因：** 空闲连接的缓冲区大量积累。

**解决方法：**

* 在内存受限的环境中设置 `FreeBufOnConnRelease: true`
* 减少 `MaxIdleConns` 以限制空闲连接数
* 如果使用压缩，减小 `MaxCompressionBuffer`
* 调低 `ConnMaxLifetime`，让连接更频繁地轮换
