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的右边)。否则会引起磁盘和内存的大量消耗;

相关推荐
Dreams_l17 小时前
初识redis(分布式系统, redis的特性, 基本命令)
数据库·redis·缓存
数据库知识分享者小北17 小时前
Qoder + ADB Supabase :5分钟GET超火AI手办生图APP
数据库·后端
yumgpkpm17 小时前
CMP (类Cloudera) CDP7.3(400次编译)在华为鲲鹏Aarch64(ARM)信创环境中的性能测试过程及命令
大数据·hive·hadoop·python·elasticsearch·spark·cloudera
hg011817 小时前
“中非咖桥 世界湘见”2025首届星沙-非洲咖啡嘉年华系列活动启动
大数据
点亮一颗LED(从入门到放弃)17 小时前
SQLite3数据库——Linux应用
linux·数据库·sqlite
济南java开发,求内推18 小时前
mongodb一个服务器部署多个节点
服务器·数据库·mongodb
武子康18 小时前
Java-148 深入浅出 MongoDB 聚合操作:$match、$group、$project、$sort 全面解析 Pipeline 实例详解与性能优化
java·数据库·sql·mongodb·性能优化·系统架构·nosql
dcloud_jibinbin18 小时前
【uniapp】体验优化:开源工具集 uni-toolkit 发布
前端·webpack·性能优化·小程序·uni-app·vue
程序猿(雷霆之王)18 小时前
MySQL——复合查询
数据库·mysql
Q264336502318 小时前
大数据实战项目-基于K-Means算法与Spark的豆瓣读书数据分析与可视化系统-基于python的豆瓣读书数据分析与可视化大屏
大数据·hadoop·机器学习·数据分析·spark·毕业设计·kmeans