# DWS SQL检查最佳实践
在SQL开发与上线前，开发人员需要对SQL进行语法和规范审查，以提前发现语法错误和不符合开发规范的写法，避免执行阶段才暴露问题。传统人工审查效率低、易遗漏，且依赖个人对规范的熟悉程度。DWS SQL检查面向该场景，对SQL语句进行静态分析与执行计划检查，帮助用户在执行前快速发现并修正问题，提升SQL质量。
本功能与SQL调优使用同一skill，按诊断深度区分使用场景：
- **SQL 检查（本文）**：只做静态分析与执行计划检查，\*\*不实际执行 SQL\*\*（不运行 EXPLAIN PERFORMANCE），适用于开发阶段快速审查
- **SQL 调优** ：在检查基础上进一步执行 EXPLAIN PERFORMANCE 采集实际性能指标，输出优化后 SQL 与性能验证（见[DWS SQL调优最佳实践](https://support.huaweicloud.com/dws-ai-dws/dws_15_0029.html)）
**Skill 地址**：hwc-dws-sql-tuning（随 hwc-dws-cli 分发，源码位于 dws-cli 仓库 agent_skills 目录）。
#### 前提条件
本 skill 依赖本地 \`hwc-dws-cli\` 与 DWS 集群连接，未安装或未配置时\*\*直接中止\*\*（无降级模式）。调用前自检：
```
hwc-dws-cli --version      # CLI 是否已安装
hwc-dws-cli config show    # 配置文件是否可读
hwc-dws-cli check-con      # 集群连接是否正常
```
先完成配置再调用：
```
hwc-dws-cli config set     # 7步向导：AK/SK → 代理 → Region → 集群 → Endpoint → 连接 → 连通性验证
```
#### 功能概述
DWS SQL 检查支持以下检查模式：
表1检查功能 
| 模式         | 说明                                  | 是否需要集群连接                    |
|:---|:---|:---|
| **语法检查**   | 检查关键字合法性、语句结构完整性、子句顺序、DWS 特有语法兼容性    | 否                           |
| **规范检查**  | 检查对象设计标准、数据操作规范、命名规范、SQL 开发最佳实践       | 否                          |
| **执行计划检查** | 检查执行计划中的下推、Stream、重分布、倾斜、估算偏差、分区裁剪、下盘 | 是（EXPLAIN VERBOSE 不执行 SQL） |
   
本检查模式对应 skill 的 full + verbose 模式：使用 EXPLAIN VERBOSE（只生成执行计划、不实际执行 SQL），不做 EXPLAIN PERFORMANCE。
#### 使用方式
在 AI Agent 对话窗口中直接提供需要检查的 SQL 语句即可触发检查，支持以下典型用法：
表2使用方式 
| 触发方式         | 示例                               |
|:---|:---|
| 检查 SQL 语法  | "检查这条 SQL 的语法：SELECT \* FROM t1" |
| 检查建表规范     | "这条 CREATE TABLE 是否符合 DWS 规范？"  |
| 验证 DWS 特有语法 | "验证这个 MERGE 语句的语法"               |
| 规范审查        | "审查我的 SQL 是否符合开发规范"              |
| 指定检查模式        | "仅做语法检查：DELETE FROM t1"           |
   
也可通过触发词快速调用：SQL检查、SQL规范、SQL审计、SQL语法、SQL优化、检查SQL、SQL review。
#### 检查规则与优化建议解读
#### 语法检查
语法检查用于发现 SQL 语句中的语法错误，完整支持 DWS 特有语法。
表3**基础语法检查** 
| 检查项       | 级别      | 说明                     | 优化建议                                                        |
|:---|:---|:---|:---|
| 词法错误        | ERROR   | SQL 文本中存在无法识别的字符或格式错误。 | 检查 SQL 文本中是否有非法字符或编码问题。                                   |
| 无效关键字       | ERROR   | 使用了 DWS 不支持的关键字。         | 替换为 DWS 支持的等效关键字。                                           |
| 保留关键字用作标识符 | ERROR   | 保留关键字不能用作标识符，除非用双引号引用。  | 使用双引号引用标识符，或改用其他名称。                                      |
| 语法结构错误     | ERROR | 缺少必选子句或关键字。              | 补充缺失的子句或关键字。                                                 |
| 子句顺序错误     | ERROR   | SQL 子句顺序不符合语法规范         | 按正确顺序排列子句：SELECT→FROM→WHERE→GROUP BY→HAVING→ORDER BY→LIMIT |
   
表4**DWS 特有语法检查** 
| 检查项                        | 级别        | 说明                                                                       | 优化建议                                         |
|:---|:---|:---|:---|
| DISTRIBUTE BY 语法          | ERROR  | 分布策略不合法，有效值为 HASH/MODULO/REPLICATION/ROUNDROBIN。                           | 使用有效的分布策略。                                     |
| PARTITION BY 语法            | ERROR    | 分区定义语法不合法，有效值为 RANGE/LIST/INTERVAL。                                      | 使用有效的分区策略。                                    |
| MERGE 语句语法                 | ERROR    | MERGE INTO...USING...ON...WHEN 结构不完整。                                    | 补全 MERGE 语句的必需子句。                             |
| EXPLAIN 语法                | ERROR | EXPLAIN 选项不合法。                                                          | 使用 DWS 支持的 EXPLAIN 选项（PERFORMANCE/WARMUP/PLAN）。 |
| COMPRESS 语法               | ERROR    | COMPRESS 选项不合法，有效值为 YES/NO。                                             | 使用 COMPRESS YES 或 COMPRESS NO。                |
| TIMECAPSULE 语法             | ERROR    | TIMECAPSULE TABLE...TO BEFORE {DROP\|TRUNCATE} 结构不合法。                     | 按正确语法结构编写 TIMECAPSULE 语句。                     |
| 资源管理对象语法                    | ERROR | CREATE RESOURCE POOL / WORKLOAD GROUP / REDACTION POLICY / OUTLINE 结构不合法。 | 参照 DWS 语法手册修正结构。                              |
| TO NODE/GROUP 语法            | ERROR   | TO NODE/GROUP 子句语法不合法。                                                   | 按正确语法编写 TO NODE/GROUP 子句。                       |
| INSERT OVERWRITE 语法       | ERROR  | INSERT OVERWRITE 语句结构不合法。                                               | 按正确语法编写 INSERT OVERWRITE 语句。                  |
| ON DUPLICATE KEY UPDATE 语法 | ERROR  | ON DUPLICATE KEY UPDATE 子句语法不合法。                                           | 按正确语法编写 ON DUPLICATE KEY UPDATE 子句。            |
| Oracle (+) 外连接语法          | WARNING | (+) 运算符使用不当。                                                            | 建议改用标准 JOIN 语法。                                 |
| Optimizer Hint 语法          | WARNING | Hint 格式不合法。                                                              | 按 /\*+ hint_name(table) \*/ 格式编写 Hint。        |
   
#### 规范检查
规范检查基于 DWS 开发设计规范，分为四类：
表5**对象设计规范** 
| 检查项                            | 级别       | 说明                                    | 优化建议                                |
|:---|:---|:---|:---|
| CREATE TABLE 缺少 DISTRIBUTE BY | ERROR      | 创建表时必须指定分布策略。                        | 添加 DISTRIBUTE BY 子句指定分布策略。          |
| CREATE TABLE 缺少主键              | INFO     | 建议定义主键约束。                               | 添加 PRIMARY KEY 约束。                 |
| CREATE TABLE 缺少表注释           | INFO     | 表未添加注释，不利于维护。                          | 添加 COMMENT ON TABLE 语句。             |
| 分布键列不在列定义中                   | WARNING    | 分布键应为表中实际存在的列。                         | 确保分布键列在列定义中存在。                      |
| 分区键与分布键相同                     | INFO      | 可能导致数据倾斜。                             | 选择不同的列作为分区键和分布键。                     |
| REPLICATION 表不宜过大            | WARNING | 大表会在每个 DN 上存储完整副本。                      | 大表使用 HASH 分布策略。                     |
| ROUNDROBIN 分布性能风险            | INFO     | 不支持本地关联，可能导致网络重分布。                     | 评估是否可使用 HASH 分布。                   |
| 自定义 TABLESPACE 需确认场景         | WARNING  | 分布式场景可能导致存储倾斜（列存 v3 表除外）。            | 确认使用场景，列存 v3 表除外。                   |
| 建议显式指定存储方式                   | WARNING | 建议通过 orientation 参数显式指定行存/列存。         | 添加 WITH (orientation=row/column)。 |
| 行存表禁止指定 compress              | ERROR   | 显式指定行存（orientation=row）时禁止使用 COMPRESS。 | 移除 COMPRESS 子句或改用列存。                |
| 大表建议设计分区                      | INFO      | 改善查询性能和数据治理效率。                        | 添加 PARTITION BY 子句。                  |
| 字段建议添加 NOT NULL              | INFO      | 优化器可在特定场景下利用 NOT NULL 优化。               | 为非空字段添加 NOT NULL 约束。                |
| 避免使用自增列                        | WARNING    | SERIAL 等类型会造成 GTM 压力。                   | 使用 SEQUENCE 替代 SERIAL。               |
| 单表索引个数不宜超过 5 个                | WARNING    | 冗余索引浪费空间，影响入库效率（需集群连接）。              | 审查并删除冗余索引。                          |
| 视图嵌套不超过三层                     | INFO       | 嵌套过深导致执行计划不稳定（需集群连接）。                   | 简化视图嵌套层级。                            |
   
表6**数据操作规范** 
| 检查项                   | 级别      | 说明                          | 优化建议                                           |
|:---|:---|:---|:---|
| 禁止使用 SELECT \*         | ERROR   | 应明确指定字段列表。                    | 替换 SELECT \* 为具体字段列表。                         |
| DELETE/UPDATE 缺少 WHERE | ERROR   | 必须包含 WHERE 条件。                 | 添加 WHERE 条件，防止误操作全表。                          |
| NOT IN 子查询性能风险         | WARNING | 建议改用 NOT EXISTS 或 LEFT JOIN。 | 将 NOT IN 改写为 NOT EXISTS 或 LEFT JOIN + IS NULL。 |
| DISTINCT 可能影响性能       | INFO      | 大数据量下排序去重可能影响性能。            | 评估是否可用 GROUP BY 替代。                          |
| 隐式类型转换风险              | WARNING  | 可能导致索引失效。                     | 确保比较操作两侧类型一致，使用显式类型转换。                      |
| LIKE 前缀通配符             | WARNING   | LIKE '%...' 无法使用索引。         | 避免前缀通配符，或使用全文检索。                             |
| OR 条件性能风险             | INFO    | 可能影响优化器选择最优计划。               | 考虑改写为 UNION ALL。                            |
| IN 列表过长                | WARNING | 超过 100 个值建议使用临时表。            | 将 IN 列表替换为临时表 JOIN。                          |
| FROM 子句中的子查询           | INFO   | 建议改用 CTE。                   | 将子查询改写为 WITH 子句（CTE）。                         |
| Oracle 外连接语法           | INFO     | 建议使用标准 JOIN。                | 将 (+) 外连接改写为 LEFT JOIN / RIGHT JOIN。           |
| INSERT 缺少字段列表           | WARNING | 依赖默认列顺序可能导致兼容性问题。            | 显式指定 INSERT 的字段列表。                             |
   
表7**命名规范** 
| 检查项           | 级别     | 说明                   | 优化建议            |
|:---|:---|:---|:---|
| 表名不符合命名规范   | WARNING | 应使用小写字母、数字和下划线，以字母开头。  | 按规范重命名表名。      |
| 列名不符合命名规范    | WARNING   | 应使用小写字母、数字和下划线，以字母开头。 | 按规范重命名列名。      |
| 使用保留关键字作标识符 | ERROR    | 可能导致语法歧义。              | 避免使用保留关键字作为标识符。 |
   
表8**SQL 开发规范** 
| 检查项                    | 级别       | 说明                          | 优化建议                         |
|:---|:---|:---|:---|
| DROP 建议使用 IF EXISTS | WARNING    | 防止对象不存在时报错。                | 添加 IF EXISTS 子句。              |
| 列存表禁止实时小批量 INSERT     | WARNING | 小 CU 膨胀影响性能。                | 列存表使用批量 INSERT 或 COPY。      |
| 列存表避免频繁 UPDATE/DELETE   | WARNING  | CU 膨胀及死锁风险。                 | 减少列存表的 UPDATE/DELETE 操作频率。 |
| 禁止执行不下推的 SQL          | ERROR     | 必须下推才能利用分布式计算（需集群连接）。     | 检查 SQL 是否可下推，改写不支持下推的写法。     |
| 过滤条件字段避免函数运算        | WARNING | 影响统计信息准确性。               | 将函数运算移至等式右侧或使用函数索引。         |
| 行存大表禁止频繁 COUNT         | WARNING  | 全表扫描 I/O 开销大。             | 使用计数器表或估算方式替代全表 COUNT。      |
| 查询建议使用 LIMIT         | INFO       | 避免超大结果集。                   | 添加 LIMIT 子句限制返回行数。            |
| 谨慎使用 WITH RECURSIVE   | WARNING  | 确保递归终止条件。                   | 检查递归终止条件，避免无限递归。            |
| 访问对象建议带 SCHEMA 前缀   | INFO     | 避免 search_path 导致访问错误对象。 | 使用 schema.table 格式访问对象。     |
   
#### 规则级别说明
表9规则级别说明 
| 级别        | 含义                   | 处理建议  |
|:---|:---|:---|
| **ERROR**  | 严重违规，可能导致执行错误或性能严重下降。 | 必须修复。 |
| **WARNING** | 潜在风险，建议优化。           | 建议修复。   |
| **INFO**    | 提示信息，供参考。            | 按需处理。  |
   
#### 检查报告说明
检查完成后生成检查报告，包含以下部分：
- **检查结果汇总**：检查规则总数、通过数、违规数，按 ERROR/WARNING/INFO 级别统计。
- **违规详情**：每条包含级别、位置（行/列）、描述、修复建议。
- **修正后的 SQL 建议**：针对违规项给出修正后的 SQL 示例及修改说明。
 
#### 使用约束与注意事项
- **不实际执行 SQL**：本检查模式不使用 EXPLAIN PERFORMANCE，不会实际执行用户 SQL（DML 不会修改数据）。
- **安全说明**：SQL 文本仅在本地处理，不发送至外部服务，不涉及凭证或认证信息。
- **建议检查流程**：先执行语法检查排除基本错误，再执行规范检查进行深度分析。
- **与 SQL 调优的关系** ：检查与调优使用同一 skill；检查不实际执行 SQL（full + verbose），调优进一步执行 EXPLAIN PERFORMANCE 采集实际性能指标并输出优化方案，详见 [DWS SQL调优最佳实践](https://support.huaweicloud.com/dws-ai-dws/dws_15_0029.html)。
 
