首页 > 数据库 >SQL大宝剑-已燃尽所有SQL的理解

SQL大宝剑-已燃尽所有SQL的理解

时间:2024-12-26 10:45:17浏览次数:8  
标签:宝剑 conf pin -- 燃尽 SQL date spark

作者:京东物流 向往

一、背景

从事数据开发将近四年,过程中有大量任务交接或阅读同事代码的场景。在这些场景中发现有些SQL读起来赏心悦目,可以一目了然地了解业务逻辑,一些复杂的业务需求实现方法也可以做到简洁优雅,同时在性能上也有良好表现。而有些SQL读起来非常艰难,时常要跨越几百行寻找WHERE条件或者关联字段,甚至充斥着大量相同的子查询命名,除了作者可能少有人能快速看懂。

 

 

 

 

为此,基于个人经验、理解与实践,我总结了一些方法和技巧,能让SQL尽量变得优雅,即兼顾代码可读性和执行性能两方面的提升。

 

二、方法与技巧

1.子查询与谓词下推

很多同事在写关联逻辑时,习惯于直接将原表关联,随后在最下方用一大段WHERE语句进行条件过滤,如下示例:


// -------------------- Bad Codes ------------------------

SELECT
    f1.pin,
    c1.site_id,
    c2.site_name
FROM
    fdm.fdm1 AS f1
LEFT JOIN cdm.cdm1 AS c1
ON
    f1.erp = lower(c1.account_number)
LEFT JOIN cdm.cdm2 AS c2
ON
    c1.site_id = c2.site_code
WHERE
    f1.start_date <= '""" + start_date + """'
    AND f1.end_date > '""" + start_date + """'
    AND f1.status = 1
    AND c1.dt = '""" + start_date + """'
    AND c2.yn = 1
GROUP BY
    f1.pin,
    c1.site_id,
    c2.site_name

这段SQL主要有两个问题:

1.cdm1和cdm2的条件写在LEFT JOIN之后,因为cdm1和cdm2是NULL补充表(NULL 补充表: 右表被称为 NULL 补充表,意味着它的存在是为了补充左表中可能缺失的值。即使在右表中没有与左表匹配的行,左表中的行仍然会被返回,右表的相关列会填充为 NULL),那么19和20行无法进行谓词下推,这会导致关联时fdm1和cdm1,cdm2先进行全表关联,再按照WHERE条件过滤分区。如果cdm1是每天全量的表,先关联全表所扫描的数据量可想而知是相当大的。

2.全表关联时没有对关联键进行NULL值处理,如果相关表的对应字段存在大量NULL值,会引起数据倾斜。

 

第一个问题涉及SQL的谓词下推,即写条件时,应该在不影响结果的情况下,尽量将过滤条件下推到join之前进行(“下推”指将条件推到靠近数据源的位置而不是SQL语句的方位)。谓词下推后,过滤条件在map端执行,减少了map端的输出,降低了数据在集群上传输的量,节约了集群的资源,也可以提升任务的性能。

对于常用的INNER JOIN和LEFT OUTER JOIN,谓词下推规则如下:

 INNER JOINLEFT OUTER JOIN  
  左表 右表 左表 右表
ON条件 下推 下推 不下推 下推
WHERE条件 下推 下推 下推 不下推

如果使用上述示例的写法,主要关注的是LEFT OUTER JOIN时WHERE语句里的条件是否会引起谓词不下推。如果不想记这些看起来很复杂的规则怎么办?可以如下所示直接使用子查询:


// -------------------- Good Codes 

标签:宝剑,conf,pin,--,燃尽,SQL,date,spark
From: https://www.cnblogs.com/Jcloud/p/18632190

相关文章

  • SQL语言1-MySQL
    1.SQL语言1.1关系型数据库的常见组件数据库:database表的集合,物理上表现为一个目录表:table,行:row列:column索引:index视图:view,虚拟的表存储过程:procedure存储函数:function触发器:trigger事件调度器:eventscheduler,任务计划用户:user权限:privilege1.2SQL语言语法标准......
  • 基于docker的MySQL、canal、Elasticsearch数据同步测试
    回顾一次容器环境的MySQL、canal、Elasticsearch数据同步MySQL和Elasticsearch安装初始化就不展示了,版本如下:sql表关键字段如下:CREATETABLE`fault_code`(`title`varchar(255)CHARACTERSETutf8mb4DEFAULTNULL,`description`varchar(512)CHARACTERSETutf8mb......
  • 容器环境的MySQL、canal、Elasticsearch数据同步测试
    回顾一次容器环境的MySQL、canal、Elasticsearch数据同步MySQL和Elasticsearch安装初始化就不展示了,版本如下:sql表关键字段如下:CREATETABLE`fault_code`(`title`varchar(255)CHARACTERSETutf8mb4DEFAULTNULL,`description`varchar(512)CHARACTERSETutf8mb......
  • MySQL中的事务(如果想知道MYSQL中有关事务的知识,那么只看这一篇就足够了!)
        前言:事务管理是数据库确保数据一致性和可靠性的核心机制,通过将一组操作作为一个整体执行,事务要么完全成功,要么完全失败,避免了数据不一致的问题,在多用户并发环境中,事务隔离级别决定了不同事务的交互方式,影响系统的性能和一致性。✨✨✨这里是秋刀鱼不做梦的BLOG......
  • centos 自动备份mysql数据库
    创建自动备份脚本创建文件mysql_auth_back.sh#!/bin/bash#source/etc/profile#以下配置信息需要根据自己情况进行编辑DB_HOST="127.0.0.1"......
  • 黑马Java面试教程_P9_MySQL
    系列博客目录文章目录系列博客目录前言1.优化1.1MySQL中,如何定位慢查询?面试文稿1.2面试官接着问:那这个SQL语句执行很慢,如何分析(=如何优化)呢?面试文稿1.3了解过索引吗?(什么是索引)1.4继续问索引的底层数据结构了解过吗?面试文稿1.5什么是聚簇索引(聚集索......
  • centos 7.9 安装mysql 8.0.39
    卸载默认的mariadb#查看是否安装自带mariadb-librpm-qa|grepmariadb#卸载自带mariadb-librpm-e--nodepsmariadb-libs#-–nodeps不需要检查依赖关系准备mysql历史版本下载地址https://downloads.mysql.com/archives/community/我这里下载的是8.0.30注意:8.0.......
  • 【论文投稿】解锁 SQL 高级技巧,让数据处理 “飞” 起来!
    【往届见刊后不到1个月检索】第四届遥感与测绘国际学术会议(RSSM2025)_艾思科蓝_学术一站式服务平台 目录前言巧用窗口函数,数据分析如有神助掌握子查询嵌套,层层剖析数据奥秘精通索引优化,加速查询一骑绝尘运用存储过程,简化复杂业务逻辑利用动态SQL,灵活应对多变需求掌......
  • Python和MySQL常用时间格式化异同
    Python和MySQL常用时间格式化异同1.Python时间格式化Python的datetime和time模块有一些常用的格式化形式,具体如下。%Y:四位数的年份,如2023。%m:两位数的月份(01-12)。%d:两位数的日期(01-31)。%H:24小时制的小时数(00-23)。%M:分钟数(00-59)。%S:秒数(00-59)。例如,"%Y-%m-%d"会将时......
  • 使用python脚本,批量修改mysql数据库表字段名称
    前提:搭建python相关环境目的:将驼峰式命名或混合大小写的字段名转换为下划线分隔的小写字段名。例如:UserName->user_name,userName->user_name一、新建脚本update_table_column_names.pyimportpymysqlimportreimportsysdefto_snake_case(name):s1......