SQL优化示例

友情链接

分布式计算框架系列文章(一)MR框架工作流程以及框架限制

分布式计算框架系列文章(二)数据倾斜现象诱因、原理、影响,以及星环对此的应对策略

分布式计算框架系列文章(三)星环科技计算引擎针对数据倾斜现象的保护机制

分布式计算框架系列文章(四)当出现数据倾斜时如何应对--倾斜key单独处理/MapJoin/星环SkewJoin的原理及使用方法

Task的数量是如何决定的

示例一

原sql

复制代码
select ... from A join B on A.key = B.key
 where A.userid>10
 and B.userid<10 and A.dt='20120417'and B.dt='20120417';

优化后sql

复制代码
select .... from (select .... from A where dt='201200417'and userid>10) a
join
(select .... from B where dt='201200417'and userid < 10) b
on a.key = b.key;

优化原因

尽量尽早地过滤数据,减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段

示例二

优化背景

如日志中,常会有信息丢失的问题,比如全网日志中的user_id,如果取其中的user_id和bmw_users关联,就会碰到数据倾斜的问题。

原sql

复制代码
select * from log a join bmw_users b
on a.user_id = b.user_id

优化后sql

解决方法1

复制代码
select * from log a join bmw_users b
on a.user_id is not null
and a.user_id = b.user_id
union all
select * from log a
where a.user_id is null

解决方法2

复制代码
select * from log a
left outer join bmw_users b
on case when a.user_id is null then concat('dp_hive',rand())
else a.user_id end = b.user_id;

优化原因

2比1效率更好,不但io少了,而且作业数也少了。

1方法log读取两次,jobs是2。

2方法job数是1 。

这个优化适合无效id(比如-99,'',null等)产生的倾斜问题。把空值的key变成一个字符串加上随机数,就能把倾斜的数据分到不同的reduce上 ,解决数据倾斜问题。因为空值不参与关联,即使分到不同的reduce上,也不影响最终的结果。

附上hadoop通用关联的实现方法(关联通过二次排序实现的,关联的列为paritionkey,关联的列c1和表的tag组成排序的group key,根据parition key分配reduce。同一reduce内根据group key排序)

示例三

优化背景

比如推广效果表要和商品表关联,效果表中的auction id列既有商品id,也有数字id,和商品表关联得到商品的信息。

建议写法

复制代码
select * from effect a
join (
select auction_id as auction_id from auctions
union all
select auction_string_id as auction_id from auctions
) b
on a.auction_id = b.auction_id

优化原因

这样写的好处,1个MR作业,商品表只读取一次,推广效果表只读取一次。把这个sql换成MR代码的话,map的时候,把a表的记录打上标签a,商品表记录每读取一条,打上标签b,变成两个<key ,value>对,<b,数字id>,<b,字符串id>。所以商品表的hdfs读只会是一次

示例四

优化背景

先join生成临时表,在union all还是写嵌套查询

原sql

复制代码
select * from (
   select * from t1
   union all
   select * from t4
   union all
   select * from t2
   join t3
   on t2.id = t3.id
   )

优化后sql

复制代码
insert overwrite table t5
select * from t2
 join t3
 on t2.id = t3.id;
select * from (t1 union all t4 union all t5) ;

优化原因

inceptor在union all优化上可以做得更智能(把子查询当做临时表),这样可以减少开发人员的负担。出现这个问题的原因应该是union all目前的优化只局限于非嵌套查询。如果写MR程序这一点也不是问题,就是multi inputs。

示例五

优化背景

使用map join解决数据倾斜的常景下小表关联大表的问题,但如果小表很大,怎么解决

原sql

复制代码
select * from log a
left outer join members b
on a.memberid = b.memberid    members有600w+的记录

优化后sql

复制代码
select /*+mapjoin(x)*/* from log a
 left outer join (
  select /*+mapjoin(c)*/ d.*
    from (
     select distinct memberid from log
      ) c
    join members d
   on c.memberid = d.memberid
    )x
 on a.memberid = b.memberid

优化原因

先根据log取所有的memberid,然后mapjoin 关联members取今天有日志的members的信息,然后在和log做mapjoin。

假如,log里memberid有上百万个,这就又回到原来map join问题。所幸,每日的会员uv不会太多,有交易的会员不会太多,有点击的会员不会太多,有佣金的会员不会太多等等。所以这个方法能解决很多场景下的数据倾斜问题。

其他优化建议

尽量原子化操作,尽量避免一个SQL包含复杂逻辑,可以使用中间表来完成复杂的逻辑;

join操作,小表要注意放在join的左边(目前TCL里面很多都小表放在join的右边)。否则会引起磁盘和内存的大量消耗;

相关推荐
DianSan_ERP10 小时前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
够快云库10 小时前
能源行业非结构化数据治理实战:从数据沼泽到智能资产
大数据·人工智能·机器学习·企业文件安全
加号310 小时前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏10 小时前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐11 小时前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
AI周红伟11 小时前
周红伟:智能体全栈构建实操:OpenClaw部署+Agent Skills+Seedance+RAG从入门到实战
大数据·人工智能·大模型·智能体
百锦再11 小时前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
B站计算机毕业设计超人11 小时前
计算机毕业设计Django+Vue.js高考推荐系统 高考可视化 大数据毕业设计(源码+LW文档+PPT+详细讲解)
大数据·vue.js·hadoop·django·毕业设计·课程设计·推荐算法
计算机程序猿学长11 小时前
大数据毕业设计-基于django的音乐网站数据分析管理系统的设计与实现(源码+LW+部署文档+全bao+远程调试+代码讲解等)
大数据·django·课程设计
B站计算机毕业设计超人11 小时前
计算机毕业设计Django+Vue.js音乐推荐系统 音乐可视化 大数据毕业设计 (源码+文档+PPT+讲解)
大数据·vue.js·hadoop·python·spark·django·课程设计