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

相关推荐
倔强的石头_10 小时前
《Kingbase护城河》——猎捕慢查询:执行计划的微观解析与索引调优实战
数据库
SelectDB11 小时前
Apache Doris Python UDF:让 SQL 直接调用 Python 生态,支撑 Agent 时代复杂业务逻辑
大数据·数据库·python
ApacheSeaTunnel14 小时前
当多表数据涌入,Apache SeaTunnel 如何巧妙化解主键冲突?
大数据·开源·数据集成·seatunnel·技术分享·数据同步
jiayou642 天前
KingbaseES 表级与列级加密完全指南
数据库·后端
GBASE2 天前
G术时刻 |GBase 8s数据库事务并发控制之封锁技术介绍(下)
数据库
xiezhr3 天前
逛GitHub发现了一款免费的带AI功能的数据库管理工具
数据库·ai编程·dba
你听得到113 天前
用户说 App 卡,但说不清在哪?我把 Flutter 监控 SDK 升级成了链路观测工作台
前端·flutter·性能优化
大大大大晴天3 天前
Hudi Metadata Table 与 Hive Sync (HMS)怎么选?
大数据
唐青枫4 天前
MySQL JSON 实战详解:从存储、查询、更新到 JSON_TABLE 与索引
sql·mysql
吃糖的小孩4 天前
给 QQ AI 机器人设计“可控记忆”:会话摘要、手动长期记忆与角色卡边界
数据库