@clickzetta/cz-cli-darwin-arm64 0.3.17 → 0.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/bin/cz-cli +0 -0
  2. package/bin/skills/clickzetta-access-control/SKILL.md +243 -0
  3. package/bin/skills/clickzetta-access-control/eval_cases.jsonl +3 -0
  4. package/bin/skills/clickzetta-access-control/references/dynamic-masking.md +86 -0
  5. package/bin/skills/clickzetta-access-control/references/grant-revoke.md +103 -0
  6. package/bin/skills/clickzetta-access-control/references/role-management.md +66 -0
  7. package/bin/skills/clickzetta-access-control/references/user-management.md +61 -0
  8. package/bin/skills/clickzetta-ai-vector-search/SKILL.md +160 -0
  9. package/bin/skills/clickzetta-ai-vector-search/eval_cases.jsonl +4 -0
  10. package/bin/skills/clickzetta-ai-vector-search/references/vector-search.md +155 -0
  11. package/bin/skills/clickzetta-batch-sync-pipeline/SKILL.md +386 -0
  12. package/bin/skills/clickzetta-cdc-sync-pipeline/SKILL.md +548 -0
  13. package/bin/skills/clickzetta-data-ingest-pipeline/SKILL.md +220 -0
  14. package/bin/skills/clickzetta-data-ingest-pipeline/eval_cases.jsonl +5 -0
  15. package/bin/skills/clickzetta-data-retention/SKILL.md +160 -0
  16. package/bin/skills/clickzetta-data-retention/eval_cases.jsonl +5 -0
  17. package/bin/skills/clickzetta-data-retention/references/lifecycle-reference.md +175 -0
  18. package/bin/skills/clickzetta-dw-modeling/SKILL.md +259 -0
  19. package/bin/skills/clickzetta-dw-modeling/eval_cases.jsonl +4 -0
  20. package/bin/skills/clickzetta-dw-modeling/references/modeling-patterns.md +100 -0
  21. package/bin/skills/clickzetta-dynamic-table/SKILL.md +112 -0
  22. package/bin/skills/clickzetta-dynamic-table/best-practices/dimension-table-join-guide.md +257 -0
  23. package/bin/skills/clickzetta-dynamic-table/best-practices/medallion-and-stream-patterns.md +124 -0
  24. package/bin/skills/clickzetta-dynamic-table/best-practices/non-partitioned-merge-into-warning.md +96 -0
  25. package/bin/skills/clickzetta-dynamic-table/best-practices/performance-optimization.md +109 -0
  26. package/bin/skills/clickzetta-external-function/SKILL.md +203 -0
  27. package/bin/skills/clickzetta-external-function/eval_cases.jsonl +4 -0
  28. package/bin/skills/clickzetta-external-function/references/external-function-ddl.md +171 -0
  29. package/bin/skills/clickzetta-file-import-pipeline/SKILL.md +156 -0
  30. package/bin/skills/clickzetta-index-manager/SKILL.md +140 -0
  31. package/bin/skills/clickzetta-index-manager/eval_cases.jsonl +5 -0
  32. package/bin/skills/clickzetta-index-manager/references/bloomfilter-index.md +67 -0
  33. package/bin/skills/clickzetta-index-manager/references/index-management.md +73 -0
  34. package/bin/skills/clickzetta-index-manager/references/inverted-index.md +80 -0
  35. package/bin/skills/clickzetta-index-manager/references/vector-index.md +81 -0
  36. package/bin/skills/clickzetta-kafka-ingest-pipeline/SKILL.md +751 -0
  37. package/bin/skills/clickzetta-kafka-ingest-pipeline/eval_cases.jsonl +5 -0
  38. package/bin/skills/clickzetta-kafka-ingest-pipeline/references/kafka-pipe-syntax.md +324 -0
  39. package/bin/skills/clickzetta-monitoring/SKILL.md +199 -0
  40. package/bin/skills/clickzetta-monitoring/eval_cases.jsonl +5 -0
  41. package/bin/skills/clickzetta-monitoring/references/job-history-analysis.md +97 -0
  42. package/bin/skills/clickzetta-monitoring/references/show-jobs.md +48 -0
  43. package/bin/skills/clickzetta-oss-ingest-pipeline/SKILL.md +537 -0
  44. package/bin/skills/clickzetta-query-optimizer/SKILL.md +156 -0
  45. package/bin/skills/clickzetta-query-optimizer/eval_cases.jsonl +5 -0
  46. package/bin/skills/clickzetta-query-optimizer/references/explain.md +56 -0
  47. package/bin/skills/clickzetta-query-optimizer/references/hints-and-sortkey.md +78 -0
  48. package/bin/skills/clickzetta-query-optimizer/references/optimize.md +65 -0
  49. package/bin/skills/clickzetta-query-optimizer/references/result-cache.md +49 -0
  50. package/bin/skills/clickzetta-query-optimizer/references/show-jobs.md +42 -0
  51. package/bin/skills/clickzetta-realtime-sync-pipeline/SKILL.md +276 -0
  52. package/bin/skills/clickzetta-sql-pipeline-manager/SKILL.md +379 -0
  53. package/bin/skills/clickzetta-sql-pipeline-manager/evals/evals.json +166 -0
  54. package/bin/skills/clickzetta-sql-pipeline-manager/references/dynamic-table.md +185 -0
  55. package/bin/skills/clickzetta-sql-pipeline-manager/references/materialized-view.md +129 -0
  56. package/bin/skills/clickzetta-sql-pipeline-manager/references/pipe.md +222 -0
  57. package/bin/skills/clickzetta-sql-pipeline-manager/references/table-stream.md +125 -0
  58. package/bin/skills/clickzetta-table-stream-pipeline/SKILL.md +206 -0
  59. package/bin/skills/clickzetta-vcluster-manager/SKILL.md +212 -0
  60. package/bin/skills/clickzetta-vcluster-manager/references/vc-cache.md +54 -0
  61. package/bin/skills/clickzetta-vcluster-manager/references/vcluster-ddl.md +150 -0
  62. package/bin/skills/clickzetta-volume-manager/SKILL.md +292 -0
  63. package/bin/skills/clickzetta-volume-manager/references/volume-ddl.md +199 -0
  64. package/bin/skills/cz-cli/SKILL.md +1 -1
  65. package/bin/skills/cz-cli-inner/SKILL.md +8 -0
  66. package/package.json +1 -1
  67. /package/bin/skills/{dt-creator → clickzetta-dynamic-table/dt-creator}/SKILL.md +0 -0
  68. /package/bin/skills/{dt-creator → clickzetta-dynamic-table/dt-creator}/references/dt-declaration-strategy.md +0 -0
  69. /package/bin/skills/{dt-creator → clickzetta-dynamic-table/dt-creator}/references/incremental-config-reference.md +0 -0
  70. /package/bin/skills/{dt-creator → clickzetta-dynamic-table/dt-creator}/references/refresh-history-guide.md +0 -0
  71. /package/bin/skills/{dt-creator → clickzetta-dynamic-table/dt-creator}/references/sql-limitations.md +0 -0
  72. /package/bin/skills/{dynamic-table-alter → clickzetta-dynamic-table/dynamic-table-alter}/SKILL.md +0 -0
@@ -0,0 +1,537 @@
1
+ ---
2
+ name: clickzetta-oss-ingest-pipeline
3
+ description: |
4
+ 搭建 ClickZetta 对象存储(OSS/S3/COS)数据导入管道,覆盖持续导入(PIPE)和批量一次性导入
5
+ 两大场景。持续导入支持 LIST_PURGE 扫描模式和 EVENT_NOTIFICATION 消息通知模式;批量导入支持
6
+ Volume + INSERT INTO 和 Volume + COPY INTO 两种方式。当用户说"对象存储导入"、"OSS 数据管道"、
7
+ "S3 数据导入"、"PIPE 持续导入"、"文件自动加载"、"存储桶数据同步"、"COS 导入"、
8
+ "批量导入 OSS"、"从 OSS 加载数据"、"Volume 导入"时触发。
9
+ 包含 PIPE 持续导入(两种 INGEST_MODE)、批量导入(Volume + COPY/INSERT)、Connection/Volume 创建、
10
+ 监控管理等 ClickZetta 特有逻辑。
11
+ Keywords: OSS, S3, COS, object storage, PIPE, COPY INTO, file ingestion
12
+ ---
13
+
14
+ # 对象存储数据管道搭建工作流
15
+
16
+ ## 适用场景
17
+
18
+ - 从对象存储(阿里云 OSS / AWS S3 / 腾讯云 COS)持续自动导入数据到 Lakehouse(PIPE 模式)
19
+ - 从对象存储批量一次性导入数据到 Lakehouse(Volume + COPY/INSERT 模式)
20
+ - 需要微批处理方式加载新增文件,实现近实时数据同步
21
+ - 需要选择扫描模式(LIST_PURGE)或消息通知模式(EVENT_NOTIFICATION)
22
+ - 需要对导入数据进行过滤转换(WHERE 条件、指定文件)
23
+ - 关键词:OSS PIPE、S3 导入、对象存储管道、文件自动加载、PIPE 持续导入、COS 数据同步、批量导入、Volume 导入
24
+
25
+ ## 前置依赖
26
+
27
+ - ClickZetta Lakehouse 账户,具备创建 PIPE、表、存储连接、Volume 等权限
28
+ - 对象存储桶可达(Endpoint、AccessKey 或 Role ARN)
29
+ - **执行环境(满足其一即可,优先使用 cz-cli)**:
30
+ - **cz-cli 路径**:已安装 cz-cli(`pip install cz-cli`),并完成 `cz-cli configure` 配置
31
+ - **MCP 路径**:clickzetta-mcp-server 工具可用(`LH_execute_query`、`LH_show_object_list` 等)
32
+
33
+ ## 环境探测(执行前必读)
34
+
35
+ 在开始任何操作前,先判断当前执行环境:
36
+
37
+ **第一步:检测 cz-cli 是否可用**
38
+ ```bash
39
+ cz-cli --version
40
+ ```
41
+ - 若命令存在 → **走 cz-cli 路径**(见本文档末尾"cz-cli 替代路径"章节)
42
+ - 若命令不存在 → 继续检测 MCP
43
+
44
+ **第二步:检测 MCP 是否可用(仅在 cz-cli 不可用时)**
45
+
46
+ 尝试调用 `LH_execute_query` 工具执行一条简单 SQL(如 `SELECT 1`)。
47
+ - 若工具存在于 tool list → **走 MCP 路径**(本文档默认路径)
48
+ - 若工具不存在 → 停止执行,提示用户:
49
+ > "当前环境既无 cz-cli 也无 MCP 工具,请安装其中之一后重试。
50
+ > cz-cli 安装:`pip install cz-cli`,然后运行 `cz-cli configure`
51
+ > MCP 安装:参考 clickzetta-mcp-server 配置文档"
52
+
53
+ ## 核心概念
54
+
55
+ ### INGEST_MODE 选择指引
56
+
57
+ | 模式 | 触发方式 | 适用场景 | 云平台支持 | 授权方式 |
58
+ |------|---------|---------|-----------|---------|
59
+ | `LIST_PURGE` | 定期扫描目录 | 通用场景,导入后删除源文件 | 所有云平台 | 密钥 或 Role ARN |
60
+ | `EVENT_NOTIFICATION` | 消息服务通知 | 低延迟场景,文件上传即触发 | 仅阿里云 OSS + AWS S3 | 仅 Role ARN |
61
+
62
+ ### 关键限制
63
+
64
+ - 每个 PIPE 需对应独立的 Volume,不可复用
65
+ - 不支持修改 COPY 语句逻辑,需删除 PIPE 重新创建
66
+ - PIPE 中的 COPY 语句不支持 `files` / `regexp` / `subdirectory` 参数
67
+ - 数据加载无法保证严格有序
68
+ - `load_history` 去重记录保留 7 天
69
+ - 修改 `COPY_JOB_HINT` 会覆盖所有已有 hints,需一次性设置全部参数
70
+ - **Volume PIPE 不支持 Kafka 专用参数**:`BATCH_INTERVAL_IN_SECONDS`、`BATCH_SIZE_PER_KAFKA_PARTITION`、`MAX_SKIP_BATCH_COUNT_ON_ERROR` 仅适用于 Kafka PIPE
71
+ - **`COPY_JOB_HINT` 必须是合法 JSON 格式**,键值都要用双引号:`'{"IGNORE_TMP_FILE": "true"}'`,不能用 `KEY=VALUE` 格式
72
+
73
+ ### 文件大小建议
74
+
75
+ - gzip 压缩文件:≈ 50MB
76
+ - CSV / PARQUET 未压缩文件:128MB ~ 256MB
77
+
78
+ ## 工作流
79
+
80
+ ### 模式 A:LIST_PURGE 扫描模式(通用)
81
+
82
+ #### 步骤 1:创建存储连接(Storage Connection)
83
+
84
+ ```sql
85
+ -- 使用 LH_execute_query 执行
86
+ -- 密钥方式(LIST_PURGE 模式支持)
87
+ CREATE STORAGE CONNECTION IF NOT EXISTS my_oss_connection
88
+ TYPE OSS
89
+ access_id = '<your_access_key_id>'
90
+ access_key = '<your_access_key_secret>'
91
+ ENDPOINT = 'oss-cn-hangzhou.aliyuncs.com';
92
+ ```
93
+
94
+ > **参数说明**:
95
+ > - `access_id`:对应阿里云控制台的 **AccessKey ID**
96
+ > - `access_key`:对应阿里云控制台的 **AccessKey Secret**
97
+ > - 也可使用大写形式 `ACCESS_KEY_ID` / `ACCESS_KEY_SECRET`
98
+ > - ⚠️ `ACCESS_KEY` / `SECRET_KEY` 会报错(缺少 `_ID` / `_SECRET` 后缀)
99
+ >
100
+ > **提示**:如果使用 Role ARN 方式(EVENT_NOTIFICATION 模式必须),参见下方"模式 B"中的 Connection 创建语法。
101
+
102
+ #### 步骤 2:创建外部 Volume
103
+
104
+ ```sql
105
+ -- 使用 LH_execute_query 执行
106
+ CREATE EXTERNAL VOLUME IF NOT EXISTS pipe_volume
107
+ LOCATION 'oss://my-bucket/data-path/'
108
+ USING CONNECTION my_oss_connection
109
+ DIRECTORY = (enable = true, auto_refresh = true)
110
+ RECURSIVE = true
111
+ COMMENT 'Volume for OSS PIPE ingestion';
112
+ ```
113
+
114
+ > **关键参数**:
115
+ > - `RECURSIVE = true`:递归扫描子目录
116
+ > - `DIRECTORY = (enable = true, auto_refresh = true)`:自动刷新目录元数据
117
+ > - ⚠️ COMMENT 不带等号:`COMMENT 'text'`(不是 `COMMENT = 'text'`)
118
+
119
+ #### 步骤 3:验证 COPY INTO 可独立运行
120
+
121
+ 在创建 PIPE 之前,先用 COPY INTO 验证数据能正常加载:
122
+
123
+ ```sql
124
+ -- 使用 LH_execute_query 执行
125
+ COPY INTO my_schema.target_table
126
+ FROM VOLUME pipe_volume
127
+ USING CSV OPTIONS ('header' = 'true', 'delimiter' = ',') PURGE=true;
128
+ ```
129
+
130
+ > **重要**:
131
+ > - PIPE 中的 COPY 语句不支持 `files`、`regexp`、`subdirectory` 参数。确保此处验证时也不使用这些参数。
132
+ > - OPTIONS 放在 PURGE=true **之前**:`USING CSV OPTIONS (...) PURGE=true`
133
+
134
+ #### 步骤 4:创建 PIPE(LIST_PURGE 模式)
135
+
136
+ ```sql
137
+ -- 使用 LH_execute_query 执行
138
+ CREATE PIPE IF NOT EXISTS my_oss_pipe
139
+ INGEST_MODE = 'LIST_PURGE'
140
+ VIRTUAL_CLUSTER = 'my_vc'
141
+ COMMENT 'OSS data pipeline - scan mode'
142
+ AS
143
+ COPY INTO my_schema.target_table
144
+ FROM VOLUME pipe_volume
145
+ USING CSV OPTIONS ('header' = 'true') PURGE=true;
146
+ ```
147
+
148
+ > **⚠️ 语法关键点**:
149
+ > - `PURGE=true` 放在最后:`USING <format> [OPTIONS (...)] PURGE=true`
150
+ > - OPTIONS 在 PURGE=true **之前**(如果需要的话)
151
+ > - 也可以不带 OPTIONS:`USING CSV PURGE=true`(推荐简洁写法)
152
+ > - COMMENT 不带等号:`COMMENT 'text'`
153
+ > - 大写 `PURGE`,小写 `true`,中间用 `=` 连接,无空格
154
+ > - **LIST_PURGE 模式必须设置** `PURGE=true`,加载成功后删除源文件(避免重复导入)
155
+ > - 即使不想删除源文件,LIST_PURGE 模式也需要此参数,否则会重复导入同一文件
156
+ > - `VIRTUAL_CLUSTER`:指定执行 PIPE 任务的虚拟集群
157
+ >
158
+ > **错误写法**(会报语法错误):
159
+ > ```sql
160
+ > -- ❌ 不要把 purge 放在 OPTIONS 里
161
+ > OPTIONS ('header' = 'true', 'purge' = 'true')
162
+ > -- ❌ OPTIONS 不能在 PURGE 之后
163
+ > USING CSV PURGE=true OPTIONS ('header' = 'true')
164
+ > -- ❌ 不要用小写或加引号
165
+ > 'purge'='true'
166
+ > ```
167
+
168
+ #### 步骤 5:验证 PIPE 状态
169
+
170
+ ```sql
171
+ -- 使用 LH_execute_query 执行
172
+ DESC PIPE EXTENDED my_oss_pipe;
173
+ ```
174
+
175
+ 确认 `pipe_execution_paused = false`(PIPE 已启动运行)。
176
+
177
+ ---
178
+
179
+ ### 模式 B:EVENT_NOTIFICATION 消息通知模式(低延迟)
180
+
181
+ > 仅支持阿里云 OSS + AWS S3。文件上传到桶后,通过消息服务(MNS/SQS)通知 Lakehouse 立即加载。
182
+
183
+ #### 前置准备(阿里云 OSS 示例)
184
+
185
+ 1. **开通阿里云 MNS 消息服务**:在阿里云控制台开通消息服务 MNS
186
+ 2. **配置 OSS 事件通知**:在 OSS 桶 → 事件通知 → 创建规则,事件类型选择 `ObjectCreated`,目标选择 MNS 队列
187
+ 3. **授权 OSS 读取权限**:创建 RAM 角色,授予 `oss:GetObject`、`oss:ListBucket` 权限,记录 Role ARN
188
+ 4. **授权 MNS 到 Lakehouse**:将 Lakehouse 服务账号添加到 MNS 队列的授权策略中
189
+
190
+ #### 步骤 1:创建存储连接(Role ARN 方式)
191
+
192
+ ```sql
193
+ -- 使用 LH_execute_query 执行
194
+ CREATE STORAGE CONNECTION IF NOT EXISTS my_oss_role_connection
195
+ TYPE OSS
196
+ ENDPOINT = 'oss-cn-hangzhou.aliyuncs.com'
197
+ ROLE_ARN = 'acs:ram::1234567890:role/clickzetta-oss-role'
198
+ REGION = 'cn-hangzhou';
199
+ ```
200
+
201
+ #### 步骤 2:创建外部 Volume
202
+
203
+ ```sql
204
+ -- 使用 LH_execute_query 执行
205
+ CREATE EXTERNAL VOLUME IF NOT EXISTS pipe_event_volume
206
+ LOCATION 'oss://my-bucket/data-path/'
207
+ USING CONNECTION my_oss_role_connection
208
+ DIRECTORY = (enable = true, auto_refresh = true)
209
+ RECURSIVE = true;
210
+ ```
211
+
212
+ #### 步骤 3:创建 PIPE(EVENT_NOTIFICATION 模式)
213
+
214
+ ```sql
215
+ -- 使用 LH_execute_query 执行
216
+ CREATE PIPE IF NOT EXISTS my_oss_event_pipe
217
+ INGEST_MODE = 'EVENT_NOTIFICATION'
218
+ VIRTUAL_CLUSTER = 'my_vc'
219
+ ALICLOUD_MNS_QUEUE = 'my-mns-queue-name'
220
+ COMMENT 'OSS data pipeline - event notification mode'
221
+ AS
222
+ COPY INTO my_schema.target_table
223
+ FROM VOLUME pipe_event_volume
224
+ USING CSV;
225
+ ```
226
+
227
+ > **参数说明**:
228
+ > - `INGEST_MODE = 'EVENT_NOTIFICATION'`:通过消息通知触发加载
229
+ > - `ALICLOUD_MNS_QUEUE`:阿里云 MNS 队列名称(AWS 使用 `AWS_SQS_QUEUE`)
230
+ > - 此模式下不需要 `PURGE=true`,因为是事件驱动而非扫描
231
+ > - COMMENT 不带等号:`COMMENT 'text'`
232
+
233
+ ---
234
+
235
+ ### 模式 C:批量导入(一次性 Volume + COPY/INSERT)
236
+
237
+ > 适用于一次性或定期批量加载对象存储中的文件,无需创建 PIPE。支持阿里云 OSS、腾讯云 COS 和 AWS S3。
238
+ > 推荐使用 GENERAL PURPOSE 类型的虚拟集群执行批量加载。
239
+
240
+ #### 使用限制
241
+
242
+ - 不支持跨云导入(源存储与 Lakehouse 环境需在同一云平台)
243
+ - 同地域建议使用内网 Endpoint(如 `oss-cn-shanghai-internal.aliyuncs.com`)以提升速度和稳定性
244
+
245
+ #### 步骤 1:创建目标表
246
+
247
+ ```sql
248
+ -- 使用 LH_execute_query 执行
249
+ CREATE TABLE IF NOT EXISTS my_schema.target_table (
250
+ id STRING,
251
+ name STRING,
252
+ amount DECIMAL(10,2),
253
+ created_date STRING
254
+ );
255
+ ```
256
+
257
+ #### 步骤 2:创建存储连接(access_id/access_key 语法)
258
+
259
+ ```sql
260
+ -- 使用 LH_execute_query 执行
261
+ CREATE STORAGE CONNECTION IF NOT EXISTS my_batch_conn
262
+ TYPE OSS
263
+ ENDPOINT = 'oss-cn-shanghai-internal.aliyuncs.com'
264
+ access_id = '<your_access_key_id>'
265
+ access_key = '<your_access_key_secret>';
266
+ ```
267
+
268
+ > **Connection 参数命名**:
269
+ > - 小写形式:`access_id` / `access_key`(推荐)
270
+ > - 大写形式:`ACCESS_KEY_ID` / `ACCESS_KEY_SECRET`(也可以)
271
+ > - ⚠️ `ACCESS_KEY` / `SECRET_KEY` 会报错(缺少后缀)
272
+
273
+ #### 步骤 3:创建外部 Volume(启用目录自动刷新)
274
+
275
+ ```sql
276
+ -- 使用 LH_execute_query 执行
277
+ CREATE EXTERNAL VOLUME IF NOT EXISTS my_batch_volume
278
+ LOCATION 'oss://my-bucket/data-path/'
279
+ USING CONNECTION my_batch_conn
280
+ DIRECTORY = (enable=true, auto_refresh=true);
281
+ ```
282
+
283
+ > **关键参数**:
284
+ > - `LOCATION`:对象存储路径,格式为 `oss://bucket/path/`
285
+ > - `USING CONNECTION`:引用已创建的存储连接
286
+ > - `DIRECTORY = (enable=true, auto_refresh=true)`:启用目录元数据并自动刷新,便于查询 Volume 中的文件列表
287
+ >
288
+ > **Volume 创建语法统一说明**:
289
+ > - ✅ 推荐语法:`LOCATION '...' USING CONNECTION conn_name`(官方文档标准写法)
290
+ > - ⚠️ 旧语法:`STORAGE_CONNECTION = conn_name LOCATION = '...'`(部分旧文档中出现,仍可使用)
291
+ > - 两种语法功能等价,建议统一使用 `LOCATION ... USING CONNECTION` 形式
292
+
293
+ #### 步骤 4a:INSERT INTO 从 Volume 导入(支持过滤转换)
294
+
295
+ ```sql
296
+ -- 使用 LH_execute_query 执行
297
+ INSERT INTO my_schema.target_table
298
+ SELECT * FROM VOLUME my_batch_volume (
299
+ id STRING,
300
+ name STRING,
301
+ amount DECIMAL(10,2),
302
+ created_date STRING
303
+ ) USING CSV OPTIONS ('header'='true', 'sep'=',')
304
+ FILES ('data_file_01.csv')
305
+ WHERE amount > 0;
306
+ ```
307
+
308
+ > **参数说明**:
309
+ > - `VOLUME my_batch_volume (...)`:指定 Volume 及列定义(Schema-on-Read)
310
+ > - `USING CSV OPTIONS (...)`:指定文件格式和解析选项
311
+ > - `FILES ('file1.csv', 'file2.csv')`:指定要加载的文件名(可选,不指定则加载全部)
312
+ > - `WHERE ...`:对数据进行过滤转换(可选)
313
+ > - INSERT INTO 方式支持 `FILES` 和 `WHERE` 参数,适合需要精细控制的场景
314
+
315
+ #### 步骤 4b:COPY INTO 从 Volume 导入(简洁语法)
316
+
317
+ ```sql
318
+ -- 使用 LH_execute_query 执行
319
+ COPY INTO my_schema.target_table
320
+ FROM VOLUME my_batch_volume (
321
+ id STRING,
322
+ name STRING,
323
+ amount DECIMAL(10,2),
324
+ created_date STRING
325
+ ) USING CSV OPTIONS ('header'='true', 'sep'=',');
326
+ ```
327
+
328
+ > **INSERT INTO vs COPY INTO 选择**:
329
+ > - `INSERT INTO`:支持 `FILES()` 指定文件、`WHERE` 过滤转换,适合精细控制
330
+ > - `COPY INTO`:语法更简洁,适合全量加载
331
+ > - 两者都支持 Schema-on-Read(在 FROM VOLUME 中定义列)
332
+ > - ⚠️ **load_history 差异**:只有 `COPY INTO` 会记录到 `load_history`,`INSERT INTO ... FROM VOLUME` 不会记录。如需去重保护,请使用 `COPY INTO`
333
+
334
+ #### 步骤 5:验证导入结果
335
+
336
+ ```sql
337
+ -- 使用 LH_execute_query 执行
338
+ SELECT COUNT(*) AS total_rows FROM my_schema.target_table;
339
+ SELECT * FROM my_schema.target_table LIMIT 10;
340
+ ```
341
+
342
+ ---
343
+
344
+ ## 监控与运维
345
+
346
+ ### 查看 PIPE 详细状态
347
+
348
+ ```sql
349
+ -- 使用 LH_execute_query 执行
350
+ DESC PIPE EXTENDED my_oss_pipe;
351
+ ```
352
+
353
+ 关键字段:
354
+ - `pipe_execution_paused`:是否暂停
355
+ - `ingest_mode`:导入模式
356
+ - `virtual_cluster`:执行集群
357
+ - `definition`:COPY 语句定义
358
+
359
+ ### 查看加载历史
360
+
361
+ ```sql
362
+ -- 使用 LH_execute_query 执行
363
+ SELECT * FROM load_history('my_schema.target_table')
364
+ ORDER BY last_load_time DESC
365
+ LIMIT 20;
366
+ ```
367
+
368
+ > `load_history` 去重记录保留 7 天。
369
+
370
+ ### 通过 query_tag 过滤 PIPE 作业
371
+
372
+ PIPE 执行的作业会自动打上 `query_tag`,格式为:`pipe.<workspace_name>.<schema_name>.<pipe_name>`
373
+
374
+ ```sql
375
+ -- 使用 LH_execute_query 执行
376
+ -- 在 JOBS 列表中过滤 PIPE 相关作业
377
+ SHOW JOBS WHERE query_tag = 'pipe.my_workspace.my_schema.my_oss_pipe';
378
+ ```
379
+
380
+ ---
381
+
382
+ ## PIPE 管理操作
383
+
384
+ ### 暂停 / 恢复 PIPE
385
+
386
+ ```sql
387
+ -- 暂停 PIPE
388
+ ALTER PIPE my_oss_pipe SET PIPE_EXECUTION_PAUSED = true;
389
+
390
+ -- 恢复 PIPE
391
+ ALTER PIPE my_oss_pipe SET PIPE_EXECUTION_PAUSED = false;
392
+ ```
393
+
394
+ ### 修改 PIPE 属性
395
+
396
+ ```sql
397
+ -- 修改虚拟集群
398
+ ALTER PIPE my_oss_pipe SET VIRTUAL_CLUSTER = 'new_vc';
399
+
400
+ -- 修改 COPY_JOB_HINT(注意:会覆盖所有已有 hints,需一次性设置全部参数)
401
+ -- 必须是合法 JSON 格式,键值都要用双引号
402
+ ALTER PIPE my_oss_pipe SET COPY_JOB_HINT = '{"max_file_count":"100","force":"false"}';
403
+ ```
404
+
405
+ > **限制**:每次 ALTER PIPE 只能修改一个属性。不支持修改 COPY 语句逻辑,需删除 PIPE 重新创建。
406
+
407
+ ### 删除 PIPE
408
+
409
+ ```sql
410
+ DROP PIPE IF EXISTS my_oss_pipe;
411
+ ```
412
+
413
+ ---
414
+
415
+ ## 故障排除
416
+
417
+ | 问题 | 排查方向 |
418
+ |------|---------|
419
+ | PIPE 创建后无数据加载 | 1. `DESC PIPE EXTENDED` 检查是否暂停 2. 确认 Volume 路径下有新文件 3. 检查 COPY INTO 是否能独立运行 |
420
+ | LIST_PURGE 模式文件未被删除 | 确认 `PURGE=true` 已设置(紧跟 `USING <format>` 之后);检查 Connection 的 AccessKey 是否有删除权限 |
421
+ | `PURGE=true` 语法错误 | OPTIONS 必须在 PURGE 之前:`USING CSV OPTIONS (...) PURGE=true`。不要写成 `USING CSV PURGE=true OPTIONS(...)` |
422
+ | EVENT_NOTIFICATION 模式无触发 | 1. 检查 MNS/SQS 队列是否收到消息 2. 确认 OSS 事件通知规则配置正确 3. 检查 Role ARN 授权 |
423
+ | 重复加载数据 | `load_history` 去重记录仅保留 7 天,超过 7 天的同名文件会被重新加载 |
424
+ | COPY_JOB_HINT 修改后部分参数丢失 | `SET COPY_JOB_HINT` 会覆盖所有已有 hints,需在一次 ALTER 中设置全部参数 |
425
+ | INSERT INTO FROM VOLUME 后 load_history 无记录 | 正常行为:只有 `COPY INTO` 会记录到 load_history,`INSERT INTO` 不会 |
426
+ | COPY INTO 报格式错误 | Volume 中有多种格式文件,使用 `FILES('xxx.json')` 指定文件 |
427
+
428
+ ## 注意事项
429
+
430
+ ### PIPE 持续导入(模式 A / B)
431
+
432
+ - 每个 PIPE 需对应独立的 Volume,不可多个 PIPE 共用同一 Volume
433
+ - PIPE 中的 COPY 语句不支持 `files` / `regexp` / `subdirectory` 参数
434
+ - 数据加载无法保证严格有序(多文件并行加载)
435
+ - 推荐文件大小:gzip 压缩 ≈ 50MB,CSV/Parquet 未压缩 128MB ~ 256MB
436
+ - `load_history` 去重记录保留 7 天,超期后同名文件可能被重复加载
437
+ - 修改 COPY 逻辑需删除 PIPE 重新创建,ALTER PIPE 不支持修改 COPY 语句
438
+
439
+ ### 批量导入(模式 C)
440
+
441
+ - Volume 支持阿里云 OSS、腾讯云 COS 和 AWS S3
442
+ - 不支持跨云导入(源存储与 Lakehouse 环境需在同一云平台)
443
+ - 同地域建议使用内网 Endpoint 以提升传输速度和稳定性
444
+ - 推荐使用 GENERAL PURPOSE 类型虚拟集群执行批量加载任务
445
+ - INSERT INTO 方式支持 `FILES()` 和 `WHERE` 参数,COPY INTO 不支持
446
+ - Connection 参数使用 `access_id`/`access_key`(小写)或 `ACCESS_KEY_ID`/`ACCESS_KEY_SECRET`(大写),不要用 `ACCESS_KEY`/`SECRET_KEY`
447
+ - ⚠️ `INSERT INTO ... FROM VOLUME` 不会记录到 `load_history`,只有 `COPY INTO` 会记录
448
+ - ⚠️ Volume 中有多种格式文件时,不指定 `FILES()` 的 COPY INTO 会尝试读取所有文件,可能因格式不匹配而失败。建议使用 `FILES('xxx.json')` 指定文件或 `SUBDIRECTORY` 指定子目录
449
+ - 上传文件到 OSS 后,`SHOW VOLUME DIRECTORY` 可能需要先执行 `ALTER VOLUME name REFRESH` 刷新目录元数据
450
+
451
+ ---
452
+
453
+ ## cz-cli 替代路径
454
+
455
+ > 仅在 cz-cli 可用且 MCP 不可用时使用本节。步骤编号与上方 MCP 路径对应。
456
+ > 所有操作通过 `cz-cli agent run` 委托给内置 agent 完成,agent 内置完整的 MCP 工具访问能力。
457
+
458
+ ### 模式 A:LIST_PURGE 扫描模式(cz-cli 版)
459
+
460
+ ```bash
461
+ # 步骤 1:创建存储连接
462
+ cz-cli agent run "创建 OSS Storage Connection,名称 <my_oss_connection>,endpoint <oss-cn-hangzhou.aliyuncs.com>,access_key <key>,secret_key <secret>" \
463
+ --format a2a --dangerously-skip-permissions
464
+
465
+ # 步骤 2:创建外部 Volume
466
+ cz-cli agent run "创建外部 Volume,名称 <pipe_volume>,使用 Connection <my_oss_connection>,路径 oss://<bucket>/<data-path>/" \
467
+ --format a2a --dangerously-skip-permissions
468
+
469
+ # 步骤 3:验证 COPY INTO 可独立运行
470
+ cz-cli agent run "用 COPY INTO 从 Volume <pipe_volume> 加载数据到表 <schema>.<table>,文件格式 CSV,有 header,验证数据能正常加载" \
471
+ --format a2a --dangerously-skip-permissions
472
+
473
+ # 步骤 4:创建 LIST_PURGE 模式 PIPE
474
+ cz-cli agent run "创建 PIPE <my_oss_pipe>,INGEST_MODE 为 LIST_PURGE,使用 VCluster <my_vc>,从 Volume <pipe_volume> 以 CSV 格式(有 header,purge=true)持续导入数据到表 <schema>.<table>" \
475
+ --format a2a --dangerously-skip-permissions
476
+
477
+ # 步骤 5:验证 PIPE 状态
478
+ cz-cli agent run "查看 PIPE <my_oss_pipe> 的详细状态,确认 pipe_execution_paused 为 false" \
479
+ --format a2a --dangerously-skip-permissions
480
+ ```
481
+
482
+ ---
483
+
484
+ ### 模式 B:EVENT_NOTIFICATION 消息通知模式(cz-cli 版)
485
+
486
+ ```bash
487
+ # 步骤 1:创建 Role ARN 方式的存储连接
488
+ cz-cli agent run "创建 OSS Storage Connection,名称 <my_oss_role_connection>,endpoint <oss-cn-hangzhou.aliyuncs.com>,使用 Role ARN <acs:ram::xxx:role/clickzetta-oss-role>,region cn-hangzhou" \
489
+ --format a2a --dangerously-skip-permissions
490
+
491
+ # 步骤 2:创建外部 Volume
492
+ cz-cli agent run "创建外部 Volume,名称 <pipe_event_volume>,使用 Connection <my_oss_role_connection>,路径 oss://<bucket>/<data-path>/" \
493
+ --format a2a --dangerously-skip-permissions
494
+
495
+ # 步骤 3:创建 EVENT_NOTIFICATION 模式 PIPE
496
+ cz-cli agent run "创建 PIPE <my_oss_event_pipe>,INGEST_MODE 为 EVENT_NOTIFICATION,使用 VCluster <my_vc>,ALICLOUD_MNS_QUEUE 为 <my-mns-queue-name>,从 Volume <pipe_event_volume> 以 CSV 格式持续导入数据到表 <schema>.<table>" \
497
+ --format a2a --dangerously-skip-permissions
498
+ ```
499
+
500
+ ---
501
+
502
+ ### 模式 C:批量导入(cz-cli 版)
503
+
504
+ ```bash
505
+ # 步骤 1:创建目标表
506
+ cz-cli agent run "在 schema <my_schema> 下创建表 <target_table>,字段:id STRING, name STRING, amount DECIMAL(10,2), created_date STRING" \
507
+ --format a2a --dangerously-skip-permissions
508
+
509
+ # 步骤 2-3:创建存储连接和 Volume
510
+ cz-cli agent run "创建 OSS Storage Connection <my_batch_conn>,endpoint <oss-cn-shanghai-internal.aliyuncs.com>,access_id <id>,access_key <key>;然后创建外部 Volume <my_batch_volume>,路径 oss://<bucket>/<data-path>/,启用目录自动刷新" \
511
+ --format a2a --dangerously-skip-permissions
512
+
513
+ # 步骤 4:从 Volume 导入数据
514
+ cz-cli agent run "从 Volume <my_batch_volume> 以 CSV 格式(有 header)将数据导入表 <my_schema>.<target_table>" \
515
+ --format a2a --dangerously-skip-permissions
516
+
517
+ # 步骤 5:验证导入结果
518
+ cz-cli agent run "查询表 <my_schema>.<target_table> 的总行数和前 10 条数据,验证导入结果" \
519
+ --format a2a --dangerously-skip-permissions
520
+ ```
521
+
522
+ ---
523
+
524
+ ### 监控与运维(cz-cli 版)
525
+
526
+ ```bash
527
+ # 查看 PIPE 状态
528
+ cz-cli agent run "查看 PIPE <my_oss_pipe> 的详细状态和加载历史" \
529
+ --format a2a --dangerously-skip-permissions
530
+
531
+ # 暂停/恢复 PIPE
532
+ cz-cli agent run "暂停 PIPE <my_oss_pipe>" \
533
+ --format a2a --dangerously-skip-permissions
534
+
535
+ cz-cli agent run "恢复 PIPE <my_oss_pipe>" \
536
+ --format a2a --dangerously-skip-permissions
537
+ ```
@@ -0,0 +1,156 @@
1
+ ---
2
+ name: clickzetta-query-optimizer
3
+ description: |
4
+ 诊断和优化 ClickZetta Lakehouse SQL 查询性能。覆盖执行计划分析、慢查询排查、
5
+ 结果缓存、小文件合并、Map Join 优化、Sort Key 推荐等完整调优工作流。
6
+ 当用户说"查询慢"、"SQL 性能优化"、"执行计划"、"EXPLAIN"、"查看 Job"、
7
+ "慢查询"、"小文件"、"OPTIMIZE"、"结果缓存"、"Result Cache"、
8
+ "Map Join"、"排序列"、"sort key"、"查询调优"、"性能诊断"时触发。
9
+ Keywords: query optimization, EXPLAIN, execution plan, slow query, cache, Map Join, Sort Key
10
+ ---
11
+
12
+ # ClickZetta 查询性能优化
13
+
14
+ ## ⚠️ 注意事项
15
+
16
+ - `OPTIMIZE` 命令只能在**通用型(GENERAL PURPOSE)计算集群**运行,分析型集群不生效
17
+ - Result Cache 默认未开启,需手动 `SET cz.sql.enable.shortcut.result.cache = true`
18
+ - Map Join 小表限制为 **1GB**,超过则失败
19
+
20
+ ---
21
+
22
+ ## 诊断流程
23
+
24
+ ```
25
+ 查询慢
26
+ ├── 1. 先看执行计划(EXPLAIN)
27
+ │ ├── 发现全表扫描 → 考虑加索引或设置 sort key
28
+ │ ├── 发现大表 JOIN → 考虑 MAPJOIN hint
29
+ │ └── 发现大量 Sort → 检查 ORDER BY 是否必要
30
+ ├── 2. 查看 Job 历史(SHOW JOBS)
31
+ │ └── 找到慢 Job → 在 Studio Job Profile 查看详细执行统计
32
+ ├── 3. 检查小文件问题
33
+ │ └── 频繁写入的表 → OPTIMIZE 合并小文件
34
+ └── 4. 利用缓存
35
+ └── 重复查询 → 开启 Result Cache
36
+ ```
37
+
38
+ ---
39
+
40
+ ## 步骤 1:分析执行计划
41
+
42
+ 阅读 [references/explain.md](references/explain.md)
43
+
44
+ ```sql
45
+ -- 快速查看物理执行计划
46
+ EXPLAIN SELECT ...;
47
+
48
+ -- 详细查看逻辑+物理执行计划
49
+ EXPLAIN EXTENDED SELECT ...;
50
+ ```
51
+
52
+ 重点关注:
53
+ - `PhysicalTableScan` 是否扫描了过多数据
54
+ - `PhysicalJoin` 的策略(是否触发 MapJoin)
55
+ - `PhysicalSort` 是否可以避免
56
+
57
+ ---
58
+
59
+ ## 步骤 2:查看慢查询 Job
60
+
61
+ 阅读 [references/show-jobs.md](references/show-jobs.md)
62
+
63
+ ```sql
64
+ -- 查看执行超过 2 分钟的 Job
65
+ SHOW JOBS IN VCLUSTER default_ap WHERE execution_time > interval 2 minute;
66
+
67
+ -- 查看最近 50 条 Job
68
+ SHOW JOBS LIMIT 50;
69
+ ```
70
+
71
+ 找到 Job ID 后,在 Studio → Job Profile 查看详细执行统计和执行计划图。
72
+
73
+ ---
74
+
75
+ ## 步骤 3:小文件优化
76
+
77
+ 阅读 [references/optimize.md](references/optimize.md)
78
+
79
+ ```sql
80
+ -- 手动合并小文件(异步,立即返回)
81
+ OPTIMIZE my_schema.orders;
82
+
83
+ -- 指定分区合并
84
+ OPTIMIZE my_schema.orders WHERE dt = '2024-01-01';
85
+
86
+ -- 同步执行(等待完成)
87
+ OPTIMIZE my_schema.orders OPTIONS('cz.sql.optimize.table.async' = 'false');
88
+
89
+ -- 写入时自动触发合并
90
+ SET cz.sql.compaction.after.commit = true;
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 步骤 4:开启结果缓存
96
+
97
+ 阅读 [references/result-cache.md](references/result-cache.md)
98
+
99
+ ```sql
100
+ -- 开启 Result Cache(SESSION 级别)
101
+ SET cz.sql.enable.shortcut.result.cache = true;
102
+
103
+ -- 关闭
104
+ SET cz.sql.enable.shortcut.result.cache = false;
105
+ ```
106
+
107
+ 命中缓存的查询通常在 15ms 内返回。在 Job Profile 中可看到 `JOB RESULT REUSE` 标记。
108
+
109
+ ---
110
+
111
+ ## 步骤 5:Map Join 与 Sort Key
112
+
113
+ 阅读 [references/hints-and-sortkey.md](references/hints-and-sortkey.md)
114
+
115
+ ```sql
116
+ -- Map Join:小表(<1GB)与大表 JOIN 时使用
117
+ SELECT /*+ MAPJOIN (small_table) */ *
118
+ FROM large_table t1
119
+ JOIN small_table t2 ON t1.id = t2.id;
120
+
121
+ -- 查看系统推荐的 Sort Key
122
+ SELECT * FROM information_schema.sortkey_candidates;
123
+
124
+ -- 应用推荐(直接执行 statement 列中的 SQL)
125
+ ALTER TABLE schema.table_name SET PROPERTIES("hint.sort.columns"="column_name");
126
+
127
+ -- 开启自动收集 Sort Key 推荐
128
+ ALTER WORKSPACE my_workspace SET PROPERTIES (auto_index='day');
129
+
130
+ -- 收集表统计信息(Sort Key 推荐为空时先执行)
131
+ ANALYZE TABLE schema.table_name;
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 常见问题
137
+
138
+ | 问题 | 排查方向 |
139
+ |---|---|
140
+ | 查询慢但执行计划看起来正常 | 检查小文件数量(`SHOW PARTITIONS EXTENDED`),考虑 OPTIMIZE |
141
+ | Result Cache 未命中 | 检查 SQL 是否完全一致、是否含 UDF 或非确定性函数、表数据是否有变更 |
142
+ | OPTIMIZE 无效 | 确认使用的是通用型(GP)集群,不是分析型集群 |
143
+ | Map Join 失败 | 小表超过 1GB,改用普通 JOIN 或拆分查询 |
144
+ | Sort Key 推荐为空 | 先执行 `ANALYZE TABLE`,再等待自动收集周期 |
145
+
146
+ ---
147
+
148
+ ## 参考文档
149
+
150
+ - [EXPLAIN](https://www.yunqi.tech/documents/EXPLAIN)
151
+ - [SHOW JOBS](https://www.yunqi.tech/documents/show-jobs)
152
+ - [Result Cache](https://www.yunqi.tech/documents/result_cache)
153
+ - [OPTIMIZE](https://www.yunqi.tech/documents/OPTIMIZE)
154
+ - [小文件优化](https://www.yunqi.tech/documents/small_file_optimization)
155
+ - [Map Join](https://www.yunqi.tech/documents/mapjoin)
156
+ - [推荐排序列](https://www.yunqi.tech/documents/auto-index)