了解那些“奇葩”SQL写法,快速写出高效率SQL(1)

简介: 了解那些“奇葩”SQL写法,快速写出高效率SQL

image.png


背景

关于sql调参数、数据倾斜可以搜到很多文章,本文主要讲解常见的SQL开发场景、‘奇葩’SQL写法并深入执行计划,带你了解如何快速写出高效率SQL。


高效写法


union直接使用效率低吗?

场景介绍

在一些业务场景中,需要将多份数据合并在一起,比如要取客户信息,客户信息存在两张表中有交叉(假设两张表中交叉的客户信息是一致的),需先将两份数据合并在一起。

写法&执行计划探查

因为两张表中数据有交叉,所以需要会先将数据去重,然后再去join。去重方式常见于:

SELECT  cst_id,cst_info
FROM    (
    SELECT  cst_id,cst_info
    FROM    @cst_info_a
    WHERE   dt = '${bizdate}'
    UNION
    SELECT  cst_id,cst_info
    FROM    cst_info_b
    WHERE   dt = '${bizdate}'
)cst_info
;

这种情况下,会理解为先将两两份数据不做任务处理就合并在一起,导致shuffle、中间临时写入的数据量和读取数据量和数据源都是一致的,然后再去做去重。因为数据量在中间过程没有没有减少,所以效率相对来说会低一些。现在来看一下执行计划:

image.png

发现执行计划是做过的优化的,已经是最优执行计划了

接下来按照理解中的高效sql写法来看一下执行计划:

-- 方式一
SELECT  cst_id,cst_info
FROM    (
    SELECT  cst_id,cst_info
    FROM    @cst_info_a
    WHERE   dt = '${bizdate}'
    GROUP BY cst_id,cst_info
    UNION
    SELECT  cst_id,cst_info
    FROM    @cst_info_b
    WHERE   dt = '${bizdate}'
    GROUP BY cst_id,cst_info
)cst_info;
--方式二
SELECT  cst_id,cst_info
FROM    (
    SELECT  cst_id,cst_info
    FROM    @cst_info_a
    WHERE   dt = '${bizdate}'
    GROUP BY cst_id,cst_info
    UNION ALL
    SELECT  cst_id,cst_info
    FROM   @cst_info_b
    WHERE   dt = '${bizdate}'
    GROUP BY cst_id,cst_info
)cst_info
GROUP BY
    cst_id,cst_info;

两种写法的执行计划一致,如下:

image.png

发现自己另外加的聚合处理,反而增加了复杂度

总结

ODPS已经对union做过优化,直接使用就可以了。并且对三个及以上的(X张)表做union,执行计划是X个MAP任务+1个REDUCE任务;不会像hive是X个MAP任务+(X-1)个REDUCE任务,还需要调整SQL才能实现最优的执行计划。


count distinct真的慢吗?

场景介绍

在开发过程中,经常会遇到一些数据探查,比如探查资产信息表中,有多少用户数,探查过程中经常会用到count distinct,那么它的效率如何?

写法&执行计划探查

探查资产信息表中近5天的用户数,常见的写法与常规认为的优化写法:

--选择近5天的资产来看
--常见写法,count distinct写法
SELECT
    COUNT(DISTINCT cst_id) AS cst_cnt
FROM @pc_bill_bal
WHERE dt BETWEEN  '${bizdate-5}' AND '${bizdate}'
;
--优化写法
SELECT  COUNT(1) AS cst_cnt
FROM    (
    SELECT
        cst_id
    FROM @pc_bill_bal
    WHERE dt BETWEEN  '${bizdate-5}' AND '${bizdate}'
    GROUP BY
        cst_id
)base
;

一般都会认为直接count distinct效率很低,是这样吗?接下来看一下两个执行计划对比

常规写法:

image.png

优化写法:

image.png

从执行计划可以看出,直接count distinct的写法被优化成了两次去重处理,一次计算总和,并不是直接全量来去重计算。再看优化写法,两次去重处理,两次计算总和,反而比count distinct多了一步,不过运行效率还是很快的。最后看一下运行时间和消耗资源,常规写法比优化写法快了28%(62s、86s),资源消耗少28%。

目录
相关文章
|
6月前
|
SQL 分布式计算 运维
了解那些“奇葩”SQL写法,快速写出高效率SQL
本文主要讲解常见的SQL开发场景、‘奇葩’SQL写法并深入执行计划,带你了解如何快速写出高效率SQL。
|
12月前
|
SQL 分布式计算 MaxCompute
了解那些“奇葩”SQL写法,快速写出高效率SQL(4)
了解那些“奇葩”SQL写法,快速写出高效率SQL
68 0
了解那些“奇葩”SQL写法,快速写出高效率SQL(4)
|
12月前
|
SQL 分布式计算 运维
了解那些“奇葩”SQL写法,快速写出高效率SQL(3)
了解那些“奇葩”SQL写法,快速写出高效率SQL
86 0
了解那些“奇葩”SQL写法,快速写出高效率SQL(3)
|
12月前
|
SQL 分布式计算 MaxCompute
了解那些“奇葩”SQL写法,快速写出高效率SQL(2)
了解那些“奇葩”SQL写法,快速写出高效率SQL
57 0
了解那些“奇葩”SQL写法,快速写出高效率SQL(2)
|
2月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
4月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
92 13
|
4月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
4月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
58 6
|
4月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
278 1