更新时间:2024-12-02 GMT+08:00
分享

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),本规则可适当放宽,但仍需关注IO消耗情况。

违反规范的影响

  • 行存表的COUNT需要扫描全表,大表场景频繁COUNT会消耗大量IO,如触发IO瓶颈会导致整体性能问题。

方案建议

  • 建议降低COUNT频率、使用结果缓存、分区级统计等方式,降低COUNT的IO消耗。

建议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

相关文档