以前的文章《更高的压缩比,更好的性能–使用ORC文件格式优化Hive》中介绍了Hive的ORC文件格式,它不但有着很高的压缩比,节省存储和计算资源以外,还经过一个内置的轻量级索引,提高查询的性能。这个内置的轻量级索引,就是下面所说的Row Group Index。性能优化
其实ORC支持的索引不止这一种,还有一种BloomFilter索引,二者结合起来,更加提高了Hive中基于ORC的查询性能。数据结构
说明一下:本文使用Hive2.0.0 + hadoop-2.3.0-cdh5.0.0做为测试环境。表lxw1234_text为text格式保存,总记录数为12000920。ide
由以前的文章知道,一个ORC文件包含一个或多个stripes(groups of row data),每一个stripe中包含了每一个column的min/max值的索引数据,当查询中有<,>,=的操做时,会根据min/max值,跳过扫描不包含的stripes。oop
而其中为每一个stripe创建的包含min/max值的索引,就称为Row Group Index,也叫min-max Index,或者Storage Index。在创建ORC格式表时,指定表参数’orc.create.index’=’true’以后,便会创建Row Group Index,须要注意的是,为了使Row Group Index有效利用,向表中加载数据时,必须对须要使用索引的字段进行排序,不然,min/max会失去意义。另外,这种索引一般用于数值型字段的查询过滤优化上。性能
看下面的例子:测试
直接执行下面的查询(未使用索引):大数据
很明显,扫描了全部记录。再使用索引查询:优化
能够看到,只扫描了部分记录,即根据Row Group Index中的min/max跳过了WHERE条件中不包含的stripes,索引有效果。spa
假若有下面的查询:htm
执行的过程大概是这样的:
先根据Row Group Index中的min/max,判断哪些stripes/file包含在内,接着逐行扫描,过滤pcid IN (‘0005E26F0DCCDB56F9041C’,’A’)的记录。
能够看到,没有全表扫描,跳过了一部分stripes。这样看来,若是where后面的id范围很大,彻底可能会包含全部的文件,再根据pcid过滤时候,又至关于全表扫描了。
对于这种查询场景的优化策略,就是下面的BloomFilter索引。
以前有篇文章《大数据去重统计之BloomFilter》,介绍过BloomFilter的原理和Java版的例子。Hive的ORC中基于此,提供了BloomFilter索引,用于性能优化。
在建表时候,经过表参数”orc.bloom.filter.columns”=”pcid”来指定为那些字段创建BloomFilter索引,这样,在生成数据的时候,会在每一个stripe中,为该字段创建BloomFilter的数据结构,当查询条件中包含对该字段的=号过滤时候,先从BloomFilter中获取如下是否包含该值,若是不包含,则跳过该stripe.
看下面的建表语句,为pcid字段创建BloomFilter索引:
而后执行上面的查询:
经过Row Group Index和Bloom Filter Index的双重索引优化,这条语句最终执行,只扫描了60000条记录,大大节省了MapTask的执行时间和资源。
以前的文章《更高的压缩比,更好的性能–使用ORC文件格式优化Hive》中介绍了Hive的ORC文件格式,它不但有着很高的压缩比,节省存储和计算资源以外,还经过一个内置的轻量级索引,提高查询的性能。这个内置的轻量级索引,就是下面所说的Row Group Index。
其实ORC支持的索引不止这一种,还有一种BloomFilter索引,二者结合起来,更加提高了Hive中基于ORC的查询性能。
说明一下:本文使用Hive2.0.0 + hadoop-2.3.0-cdh5.0.0做为测试环境。表lxw1234_text为text格式保存,总记录数为12000920。
由以前的文章知道,一个ORC文件包含一个或多个stripes(groups of row data),每一个stripe中包含了每一个column的min/max值的索引数据,当查询中有<,>,=的操做时,会根据min/max值,跳过扫描不包含的stripes。
而其中为每一个stripe创建的包含min/max值的索引,就称为Row Group Index,也叫min-max Index,或者Storage Index。在创建ORC格式表时,指定表参数’orc.create.index’=’true’以后,便会创建Row Group Index,须要注意的是,为了使Row Group Index有效利用,向表中加载数据时,必须对须要使用索引的字段进行排序,不然,min/max会失去意义。另外,这种索引一般用于数值型字段的查询过滤优化上。
看下面的例子:
直接执行下面的查询(未使用索引):
很明显,扫描了全部记录。再使用索引查询:
能够看到,只扫描了部分记录,即根据Row Group Index中的min/max跳过了WHERE条件中不包含的stripes,索引有效果。
假若有下面的查询:
执行的过程大概是这样的:
先根据Row Group Index中的min/max,判断哪些stripes/file包含在内,接着逐行扫描,过滤pcid IN (‘0005E26F0DCCDB56F9041C’,’A’)的记录。
能够看到,没有全表扫描,跳过了一部分stripes。这样看来,若是where后面的id范围很大,彻底可能会包含全部的文件,再根据pcid过滤时候,又至关于全表扫描了。
对于这种查询场景的优化策略,就是下面的BloomFilter索引。
以前有篇文章《大数据去重统计之BloomFilter》,介绍过BloomFilter的原理和Java版的例子。Hive的ORC中基于此,提供了BloomFilter索引,用于性能优化。
在建表时候,经过表参数”orc.bloom.filter.columns”=”pcid”来指定为那些字段创建BloomFilter索引,这样,在生成数据的时候,会在每一个stripe中,为该字段创建BloomFilter的数据结构,当查询条件中包含对该字段的=号过滤时候,先从BloomFilter中获取如下是否包含该值,若是不包含,则跳过该stripe.
看下面的建表语句,为pcid字段创建BloomFilter索引:
而后执行上面的查询:
经过Row Group Index和Bloom Filter Index的双重索引优化,这条语句最终执行,只扫描了60000条记录,大大节省了MapTask的执行时间和资源。