SELECT操作规范
规则3.7 禁止执行不下推的SQL
GaussDB(DWS)为分布式架构,SQL语句必须下推才能分利用分布式的计算资源,达到性能最优。
违反规范的影响:
- 不下推的SQL执行性能差,严重情况会导致CN资源瓶颈,影响整体业务。
方案建议:
- 不使用不下推的语法和不下推的函数,具体参考语句下推调优。
规则3.8 禁止多表关联时缺少关联条件
违反规范的影响:
- 多表关联时不指定关联条件就是求笛卡尔积,极易导致结果集膨胀,造成性能和资源过载风险。
方案建议:
- 多表关联时明确每张表的过滤条件和关联条件,避免出现缺少过滤条件和关联条件的情况。
规则3.9 多表关联字段数据类型要保持一致
违反规范的影响:
- 关联字段类型不一致,导致额外的类型转换开销,且影响数据重分布的策略,无法生成最优计划。
方案建议:
- 多表关联场景,关联的字段均使用同样的数据类型。
建议3.10 尽量避免对关联条件字段和过滤条件字段进行函数运算
违反规范的影响:
- 对关联条件字段和过滤条件字段进行函数运算,导致优化器无法获取准确的字段统计信息,无法生成最优计划,影响执行性能。
方案建议:
- 关联条件字段之间直接比较,如有需要运算后比较的场景需在数据入库前进行预处理。
- 过滤条件和常量比较时,只对常量列进行函数运算,字段列不进行函数运算,例如:
1 2 3 4 5 6 7 8 9
SELECT id, from_image_id, from_person_id, from_video_id FROM face_data WHERE SS.DEL_FLAG = 'N' AND NVL(SS.DELETE_FLAG, 'N') = 'N' 改写为: SELECT id, from_image_id, from_person_id, from_video_id FROM face_data where SS.DEL_FLAG = 'N' AND (SS.DELETE_FLAG = 'N' or SS.DELETE_FLAG is null)
建议3.11 资源高消耗型SQL需做好压力测试和并发管控
违反规范的影响:
- 存储和计算资源过载,整体运行性能下降。
方案建议:
高资源消耗型SQL的主要特征:
- 大量UNION ALL
- 大量AGG(COUNT DISTINCT、MAX等)
- 大量表JOIN
- 大量STREAM算子(计划维度)
针对上述SQL需进行压力测试和并发管控,如果超出资源能力,则必须进行业务优化后再重新评估上线。
规则3.12 禁止针对行存大表的频繁COUNT
磁盘能力强的场景(如SSD),本规则可适当放宽,但仍需关注I/O消耗情况。
违反规范的影响:
- 行存表的COUNT需要扫描全表,大表场景频繁COUNT会消耗大量I/O,如触发I/O瓶颈会导致整体性能问题。
方案建议:
- 建议降低COUNT频率、使用结果缓存、分区级统计等方式,降低COUNT的I/O消耗。
建议3.13 避免查询返回超大结果集(数据导出场景除外)
违反规范的影响:
- 在实际不需要查看所有结果的场景,查询超大结果集会浪费大量资源。
方案建议:
- 查询使用LIMIT,只返回必要数量的结果。
- 真实需要查询大量结果集的场景,使用游标进行分段获取,合理设置FETCH SIZE。
建议3.14 查询时避免使用“SELECT *”写法
违反规范的影响:
- 查询实际不需要的列,增加计算负担,浪费计算资源。
方案建议:
- SELECT时明确列出查询所需字段,提升查询的有效性能。
建议3.15 谨慎使用递归语句(WITH RECURSIVE),明确终止条件,确保递归可终止
违反规范的影响:
- 无明确终止条件,递归陷入死循环,无法完成。
- 重复数据过多,递归产生大量重复数据,占用大量资源。
方案建议:
- 根据业务表数据量和数据特征设计合理的递归终止条件。
建议3.16 访问对象(表,函数等)时带上SCHEMA名称
违反规范的影响:
- 不指定SCHEMA名称前缀,实际会根据当前search_path中表空间列表,依次搜索所有表空间直到找到匹配的表作为目标表,可能因SCHEMA切换导致访问到非预期的表。
方案建议:
- 访问表和函数对象时显式指定“SCHEMA.”前缀,增强可读性、稳定性、可移植性。
建议3.17 针对SQL标记注释,唯一标识SQL的归属
违反规范的影响:
- 业务溯源能力较差,只能通过数据库、用户名、客户端IP信息找开发人员确认。
方案建议:
- 建议使用query_band,例如:
1
SET query_band='JobName=abc;AppName=test;UserName=user';
- 每个SQL开头标记注释,唯一标识SQL的归属,方便问题定位及应用性能分析,命名建议为:
/* 模块名_工具名_作业名_步骤 */,如: /* mca_python_xxxxxx_step1 */ insert into xxx select … from