Hadoop平台中SQL优化的四个思路

要正确的优化SQL,必须能快速定位性能瓶颈点,或者说快速找到SQL主要的开销所在。最慢的设备通常是瓶颈点的成因,如文件下载时的瓶颈点可能是网络速度,本地文件复制时的瓶颈点可能在于硬盘性能。

为了快速找到SQL的性能瓶颈点,首先需要读者对各种设备的性能数据有一些基本的认识,如千兆网络带宽是1000Mbps,硬盘转速为每分钟7200/10000转等。

下图数据给出了一些当前主流的计算机性能指标。

图1 I/O各层次硬件性能汇总

如上图所示,每种设备基本上都有两个重要指标:

  • 延时(响应时间):反映硬件的突发处理能力。
  • 带宽(吞吐量):反映硬件持续处理能力。

通过比较这两种指标,可以发现计算机各系统硬件性能从高到低依次为:CPU→Cache(L1-L2-L3)→内存→SSD硬盘→网络→硬盘。

比较性能之后,我们再看一下每种硬件在Hadoop系统进行SQL运算时负责的主要工作:

CPU及内存:缓存数据访问、比较、排序、事务检测、SQL解析、函数或逻辑运算、JOIN、数据加解密、加解压等;

网络:结果或者Shuffle数据的传输、SQL请求、远程数据访问等;

硬盘:数据访问、数据写入、日志记录、外排序、Shuffle等。

将以上陈列的各硬件性能指标及其工作内容结合考虑,在Hadoop集群中提升SQL的执行性能就是要尽量做到以下四点:

  1. 减少数据访问(减少磁盘访问)
  2. 减少中间结果量(减少网络传输或磁盘访问)
  3. 减少交互次数(减少网络传输、减少调度开销)
  4. 改进算法,减少服务器CPU开销(减少CPU及内存开销)

注:实际优化时,除了以上四点还应注意任务分配要均匀且大小适中。

总而言之,优化的基本思想就是反复迭代,合理利用资源,综合平衡各种开销,以求达到最优效果。下面将简单介绍这四种优化思路,以及分别可采用的方法。

1. 减少数据访问

传统关系型数据库例如MySQL、Oracle等,通常通过提供索引来实现减少数据访问、提升访问速度,但是由于Hadoop不维护键(Key)的特性,因而SQL on Hadoop引擎一般不提供对传统索引的支持,或者功能不像传统索引一样完备。

为了达到和索引相似的优化目的,即加快过滤扫描,SQL on Hadoop产品通常提供其他功能用以弥补。以星环科技的Inceptor为例,其本身并没有可用于控制的传统意义上的索引,但是提供了分区、分桶,以及MinMaxFilter、BloomFilter以及RowFilter等用于批量过滤数据的过滤器。这些功能的原理通常是通过把相似、相关或者相等的数据进行归类以减少查询搜索的范围,或者建立基于列式存储的扫描方式尽可能的减少无关数据的读取。使用者需要结合实际语句,把这些功能进行高效组合,合理运用在刀刃上。

2. 返回更少的数据

返回更少的数据就是要求在构造SQL语句时,只SELECT需要的列。因为每个字段的提取都是一个复杂的解析过程,且占用内存,所以为了减少不必要的查询时间,请读者最好仅返回需要的字段。比如减少“SELECT *”的使用,因为大多数情况是不需要所有字段的数据的。

【例1】如果某用户提交了这样的语句,但是实际需要的只有id、name两个字段:


  1. SELECT * FROM product WHERE company_id = 456723  
  2. LIMIT 100; 

为了加快执行速度,建议将语句写为:


  1. SELECT id, name FROM product  
  2. WHERE company_id = 456723  
  3. LIMIT 10; 

另外若SELECT的结果是用于判断某些条件是否成立,例如EXISTS操作,就更加没必要返回所有数据:

【例2】某个包含关联的语句,在优化调整前,EXISTS内部返回了满足条件的所有字段值:


  1. SELECT … FROM table_name_2 WHERE  
  2. … EXISTS (  
  3. SELECT * FROM table_name_1  
  4. WHERE table_name_1.col1 = table_name_2.col1  
  5. ); 

但是EXISTS的返回仅用于判断满足条件的记录存在与否,所以EXISTS内部无需返回所有字段。因此可以将EXISTS子句中的“SELECT *”优化为“SELECT 1”:


  1. SELECT … FROM table_name_2 WHERE  
  2. … EXISTS (  
  3. SELECT 1 FROM table_name_1  
  4. WHERE table_name_1.col1 = table_name_2.col1  
  5. ); 

3. 减少交互次数

减少交互次数就是减少网络通信的交互次数。这里分享与此相关的三种优化情况。

Batch DML

批量方式处理DML可以大幅度减少和服务器的交互次数。Inceptor数据库访问框架提供了批量提交的接口以服务于大量插入数据。当用户一次性往一个表中插入1000万条数据时,试想如果采用普通的Insert,将和服务器发生1000万次交互,按每秒钟向数据库服务器提交10000次估算,完成所有工作需要消耗1000秒。但是如果采用批量提交模式,每1000条提交一次,和服务器的交互次数就减少至1万次,交互次数大大减少,耗时缩短为原来的千分之一。

采用Batch操作虽然不会大量减少数据库服务器的物理I/O,但是会大幅减少客户端与服务端的交互次数,从而降低多次发起的网络延时开销,以及数据库的CPU开销。

In List

进行数据扫描时,有时会遇到这样的情况:到手多个ID,需要查询与这些ID相关的记录。有两种方式实现:单条提交或者批量提交。

单条处理就是采用一个ID发一个请求的方式传送给数据库:


  1. for: var in ids[] do begin  
  2. SELECT * FROM table_name WHERE id=:var;  
  3. end; 

这种方法会增加与服务器的交互次数,显然和减少交互次数的思想背道而驰,固然是不推荐的。建议用ID InList的方式批量提交,可以把多次交互压缩在一次访问中完成,加速查询:


  1. SELECT * FROM table_name  
  2. WHERE id IN ids[]; 

使用存储过程

Inceptor支持存储过程,合理的利用存储过程有助于提高系统性能。存储过程是由SQL语句组成的完成特定功能的代码块。每个代码块在创建时都需要命名,用户通过访问对应名称调用它们。存储过程中的代码都是已经编译过的,所以调用的时候可以跳过编译阶段直接执行,而且由于其直接存储在数据库中,可以避免SQL语句的重复传输。

总体而言使用存储过程有以下两方面的好处:

减少编译次数提高了执行效率。

在网络交互中代替了大量的SQL语句,使用者只需传递一些必要参数,帮助减少网络通信量,提升通信效率。

4. 减少数据库服务器

CPU运算SQL中会包含各种各样的操作和计算要求CPU参与运算,其中有一些计算并非必须,可以人为避免。例如,进行对比运算时,对于不匹配的类型,系统要对操作数进行类型转换,导致加重CPU负担。所以,对于数字和日期类型,建议用户在执行计算前先进行类型转换,使各操作数的类型匹配,或者建表时尽可能的把字段规划成相同的数据类型。

另外,对于SQL中的逻辑运算符,Inceptor通常对普通比较运算符(如等于、不等)有较好的表现,但是对于服务器CPU需求量很高的操作,需要用户保持警惕。如LIKE操作,该模糊查询对CPU的要求一般较高,特别是检查的记录有上万条及以上时,系统表现比较糟糕。建议用户根据业务语义尽量用In-List实现LIKE,在In-List中包含LIKE所有可能的匹配选项。

【例3】如下所示模糊查询语句:


  1. SELECT * FROM table_name  
  2. WHERE column_name LIKE ‘%abc%’; 

若已知该列字段值仅有三种取值‘cabc’、‘abce’、‘cabe’,上面的语句可以等价为这样的表达方式:


  1. SELECT * FROM table_name 
  2. WHERE column_name IN (‘cabc’, ‘abce’, ‘cabe’); 

【例4】如果In-List数据可用一条SELECT语句查询得到,最好让一张中间小表作为In列表内部数据,然后采用内外查询关联的方式进行检索:


  1. SELECT * FROM table_name 
  2. WHERE column_name IN ( 
  3. SELECT col_name FROM tbl WHERE gender = ‘f’ 
  4. ); 

总结本文分享了四种在Hadoop平台中常用的SQL优化思路,实际上每种思路在具体应用时都可以引申出很多不同的方法,介绍这些思路的目的在于为用户在选择SQL优化手段时提供一些明确方向。

最后大致总结一下这些优化思路的适用场合:

  1. 在过滤扫描阶段考虑如何减少数据访问;
  2. 构造SELECT子句时应思考应该如何减少返回数据;
  3. 当执行涉及向服务器发起交互请求的操作时,应当选择减少交互次数的合适方法;
  4. 必要时进行人工处理以减少不必要的CPU计算。

如果用户能够考虑并兼顾这四个方面,相信由此构造的SQL语句会在Hadoop平台中有更好的执行性能。

本文作者:星环科技

来源:51CTO

时间: 2024-07-30 15:14:16

Hadoop平台中SQL优化的四个思路的相关文章

分页优化的四种方式

转自:http://www.orczhou.com/index.php/2009/03/four-way-pager-display/ 很久以前读了一篇关于分页的文章,后来越想越有道理,最近又重新找出来,并做了翻译,原文参考:Four ways to optimize paginated displays. 翻译背景:在大数据量的情况下,原本很简单的分页如果没有处理好,你会发现分页的请求会消耗你大量的数据库时间.如果你遇到了这个问题,文章给了你几个很好的解决的方案.当然,初学者若能看完这篇文章,

一次耐人寻味的SQL优化:除了SQL改写,还要考虑什么?

作者介绍 黄浩,现任职于中国惠普,从业十年,始终专注于SQL.在华为做项目的两年多,做过大大小小的SQL多达1500个.闲暇之余,喜欢将部分案例写成博客发表在华为内部数据库官方社区,反响强烈,已连续四个月蝉联该社区最佳博主.目前已开设专栏"优哉悠斋",成为首个受邀社区"专家访谈"的外协人员.   这是一次值得纪念的优化,值得回忆的内容非常丰富,虽然这个SQL本身并不复杂,几乎是一个相对规范式的SQL,所以,这次优化的重点并不是SQL的改写,而更多的是业务需求.物理模

阿里云慢SQL优化挑战大赛分析

[背景] 阿里云慢SQL优化挑战赛:https://yq.aliyun.com/articles/136363?spm=5176.100240.searchblog.32.oYlhtr [考点分析] 本次慢SQL优化挑战赛的题目全部来自于生产案例,将众多考察点揉合到一条SQL中,主要考虑了以下方面: 表设计:考察字符和数字字段定义,字符集大小写校验,时间字段存储. 驱动表:考察多表join时候最优的连接顺序. 索引优化:考察索引消除排序以,索引隐式转换,覆盖索引避免回表的问题. 执行计划:使用e

被埋没的SQL优化利器——Oracle SQL monitor

转载声明:本文为DBA+社群原创文章,转载必须连同本订阅号二维码全文转载,并注明作者名字及来源:DBA+社群(dbaplus).    据说,在Oracle企业版数据库中有一个免费的工具,乃SQL优化之利器,那就是Oracle SQL monitor.下面,由DBA+社群原创专家周俊,给大家科普一下这一被埋没的神器.   专家简介    周俊 DBA+社群原创专家   具有14年以上Oracle数据库技术支持经验,在IBM的7年间担任华东区非IBM logo产品技术支持团队team leader

冻结时间倒数前一小时,记一次步步惊心的SQL优化

作者介绍 黄浩:从业十年,始终专注于SQL.十年一剑,十年磨砺.3年通信行业,写就近3万条SQL:5年制造行业,遨游在ETL的浪潮:2年性能优化,厚积薄发自成一家.   9月版本是一个大版本,上上下下都在紧锣密鼓地张罗着.   9月10日版本上线,8日开始,能明显的感觉到大战前战鼓擂动人喊马嘶的紧张氛围.项目组人头簇动,奔走如织:邮箱内,关于BUG单通报及处理意见的邮件,在这个骄阳似火的南方,犹如冷冽寒冬时北方的雪花般漫天纷飞.     14:40  主动出击   快下午三点钟的时候,一片雪花悄

一次马失前蹄的SQL优化:递归查询引发的血案

作者介绍 黄浩:从业十年,始终专注于SQL.十年一剑,十年磨砺.3年通信行业,写就近3万条SQL:5年制造行业,遨游在ETL的浪潮:2年性能优化,厚积薄发自成一家.   在上个案例分享时,有读者表示"很想知道,作者失败的时候是怎么办?",并且看热闹不嫌事大,要求"来一篇文章呗".好吧,正所谓,常在河边走,哪有不湿鞋.本人在SQL优化领域摸爬滚打多年,"接客"无数,难免会遇到些难以伺候的"官人",本文就跟大家分享一次不成功的优化

db2-求数据库大神帮忙,SQL优化

问题描述 求数据库大神帮忙,SQL优化 小弟数据库方面的知识非常浅薄,只会写sql语句实现查询,但是确不会做优化,以下有两个sql语句,在数据库中执行的非常慢,DB2,有没有数据库大神,帮忙优化一下,不胜感激. --单证号是否连续 select * from ( select double(replace(c.doc_nbr, 'QZ', '')) as nbr,c.doc_id, b.pip_nbr,c.inv_code,'1' as t from op_bill a,op_bill_deta

【重磅干货】看了此文,Oracle SQL优化文章不必再看!

听"俊"一席话,胜读十年书.看了这篇由DBA+社群联合发起人丁俊大师(网名:dingjun123)分享的SQL优化大作,其他Oracle SQL优化文章都不必再看了!   专家简介    丁俊 网名:dingjun123 DBA+社群联合发起人   性能优化专家,Oracle ACEA,ITPUB开发版资深版主.8年电信行业从业经验,在某大型电信系统提供商工作7年,任资深工程师,从事过系统开发与维护.业务架构和数据分析.系统优化等工作.擅长基于ORACLE的系统优化,精通SQL.PL/

oracle sql 优化 ,请各位看看哈

问题描述 oracle sql 优化 ,请各位看看哈 select e.id, e.content, e.write_time, e.orig_id, e.from_client, e.images, u.nickname || '(' || u.realname || ')' as writer, a.orig_content, b.praise_times, c.comment_times, d.transfer_times from wx_essay e left join wx_user