DWS SQL检查最佳实践
在SQL开发与上线前,开发人员需要对SQL进行语法和规范审查,以提前发现语法错误和不符合开发规范的写法,避免执行阶段才暴露问题。传统人工审查效率低、易遗漏,且依赖个人对规范的熟悉程度。DWS SQL检查面向该场景,对SQL语句进行静态分析与执行计划检查,帮助用户在执行前快速发现并修正问题,提升SQL质量。
本功能与SQL调优使用同一skill,按诊断深度区分使用场景:
- SQL 检查(本文):只做静态分析与执行计划检查,**不实际执行 SQL**(不运行 EXPLAIN PERFORMANCE),适用于开发阶段快速审查
- SQL 调优:在检查基础上进一步执行 EXPLAIN PERFORMANCE 采集实际性能指标,输出优化后 SQL 与性能验证(见DWS SQL调优最佳实践)
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 检查支持以下检查模式:
| 模式 | 说明 | 是否需要集群连接 |
|---|---|---|
| 语法检查 | 检查关键字合法性、语句结构完整性、子句顺序、DWS 特有语法兼容性 | 否 |
| 规范检查 | 检查对象设计标准、数据操作规范、命名规范、SQL 开发最佳实践 | 否 |
| 执行计划检查 | 检查执行计划中的下推、Stream、重分布、倾斜、估算偏差、分区裁剪、下盘 | 是(EXPLAIN VERBOSE 不执行 SQL) |
本检查模式对应 skill 的 full + verbose 模式:使用 EXPLAIN VERBOSE(只生成执行计划、不实际执行 SQL),不做 EXPLAIN PERFORMANCE。
使用方式
在 AI Agent 对话窗口中直接提供需要检查的 SQL 语句即可触发检查,支持以下典型用法:
| 触发方式 | 示例 |
|---|---|
| 检查 SQL 语法 | "检查这条 SQL 的语法:SELECT * FROM t1" |
| 检查建表规范 | "这条 CREATE TABLE 是否符合 DWS 规范?" |
| 验证 DWS 特有语法 | "验证这个 MERGE 语句的语法" |
| 规范审查 | "审查我的 SQL 是否符合开发规范" |
| 指定检查模式 | "仅做语法检查:DELETE FROM t1" |
也可通过触发词快速调用:SQL检查、SQL规范、SQL审计、SQL语法、SQL优化、检查SQL、SQL review。
检查规则与优化建议解读
语法检查
语法检查用于发现 SQL 语句中的语法错误,完整支持 DWS 特有语法。
| 检查项 | 级别 | 说明 | 优化建议 |
|---|---|---|---|
| 词法错误 | ERROR | SQL 文本中存在无法识别的字符或格式错误。 | 检查 SQL 文本中是否有非法字符或编码问题。 |
| 无效关键字 | ERROR | 使用了 DWS 不支持的关键字。 | 替换为 DWS 支持的等效关键字。 |
| 保留关键字用作标识符 | ERROR | 保留关键字不能用作标识符,除非用双引号引用。 | 使用双引号引用标识符,或改用其他名称。 |
| 语法结构错误 | ERROR | 缺少必选子句或关键字。 | 补充缺失的子句或关键字。 |
| 子句顺序错误 | ERROR | SQL 子句顺序不符合语法规范 | 按正确顺序排列子句:SELECT→FROM→WHERE→GROUP BY→HAVING→ORDER BY→LIMIT |
| 检查项 | 级别 | 说明 | 优化建议 |
|---|---|---|---|
| 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 开发设计规范,分为四类:
| 检查项 | 级别 | 说明 | 优化建议 |
|---|---|---|---|
| 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 | 嵌套过深导致执行计划不稳定(需集群连接)。 | 简化视图嵌套层级。 |
| 检查项 | 级别 | 说明 | 优化建议 |
|---|---|---|---|
| 禁止使用 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 的字段列表。 |
| 检查项 | 级别 | 说明 | 优化建议 |
|---|---|---|---|
| 表名不符合命名规范 | WARNING | 应使用小写字母、数字和下划线,以字母开头。 | 按规范重命名表名。 |
| 列名不符合命名规范 | WARNING | 应使用小写字母、数字和下划线,以字母开头。 | 按规范重命名列名。 |
| 使用保留关键字作标识符 | ERROR | 可能导致语法歧义。 | 避免使用保留关键字作为标识符。 |
| 检查项 | 级别 | 说明 | 优化建议 |
|---|---|---|---|
| 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 格式访问对象。 |
规则级别说明
| 级别 | 含义 | 处理建议 |
|---|---|---|
| ERROR | 严重违规,可能导致执行错误或性能严重下降。 | 必须修复。 |
| WARNING | 潜在风险,建议优化。 | 建议修复。 |
| INFO | 提示信息,供参考。 | 按需处理。 |
检查报告说明
检查完成后生成检查报告,包含以下部分:
- 检查结果汇总:检查规则总数、通过数、违规数,按 ERROR/WARNING/INFO 级别统计。
- 违规详情:每条包含级别、位置(行/列)、描述、修复建议。
- 修正后的 SQL 建议:针对违规项给出修正后的 SQL 示例及修改说明。
使用约束与注意事项
- 不实际执行 SQL:本检查模式不使用 EXPLAIN PERFORMANCE,不会实际执行用户 SQL(DML 不会修改数据)。
- 安全说明:SQL 文本仅在本地处理,不发送至外部服务,不涉及凭证或认证信息。
- 建议检查流程:先执行语法检查排除基本错误,再执行规范检查进行深度分析。
- 与 SQL 调优的关系:检查与调优使用同一 skill;检查不实际执行 SQL(full + verbose),调优进一步执行 EXPLAIN PERFORMANCE 采集实际性能指标并输出优化方案,详见 DWS SQL调优最佳实践。