zoukankan      html  css  js  c++  java
  • 转:Hive性能优化之ORC索引–Row Group Index vs Bloom Filter Index

    之前的文章《更高的压缩比,更好的性能–使用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。

    Row Group Index

    由之前的文章知道,一个ORC文件包含一个或多个stripes(groups of row data),每个stripe中包含了每个columnmin/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会失去意义。另外,这种索引通常用于数值型字段的查询过滤优化上。

    看下面的例子:

    1. CREATE TABLE lxw1234_orc2 stored AS ORC
    2. TBLPROPERTIES
    3. ('orc.compress'='SNAPPY',
    4. 'orc.create.index'='true',
    5. 'orc.bloom.filter.fpp'='0.05',
    6. 'orc.stripe.size'='10485760',
    7. 'orc.row.index.stride'='10000')
    8. AS
    9. SELECT CAST(siteid AS INT) AS id,
    10. pcid
    11. FROM lxw1234_text
    12. DISTRIBUTE BY id sort BY id;

    直接执行下面的查询(未使用索引):

    1. SELECT COUNT(1) FROM lxw1234_orc1 WHERE id >= 1382 AND id <= 1399;

    orc index

    很明显,扫描了所有记录。再使用索引查询:

    1. set hive.optimize.index.filter=true;
    2. SELECT COUNT(1) FROM lxw1234_orc1 WHERE id >= 1382 AND id <= 1399;

    orc index

    可以看到,只扫描了部分记录,即根据Row Group Index中的min/max跳过了WHERE条件中不包含的stripes,索引有效果。

    假如有下面的查询:

    1. SET hive.optimize.index.filter=true;
    2. SELECT COUNT(1) FROM lxw1234_orc1 WHERE id >= 0 AND id <= 1000
    3. AND pcid IN ('0005E26F0DCCDB56F9041C','A');

    执行的过程大概是这样的:

    先根据Row Group Index中的min/max,判断哪些stripes/file包含在内,接着逐行扫描,过滤pcid IN (‘0005E26F0DCCDB56F9041C’,’A’)的记录。

    orc index

    可以看到,没有全表扫描,跳过了一部分stripes。这样看来,如果where后面的id范围很大,完全可能会包含所有的文件,再根据pcid过滤时候,又相当于全表扫描了。

    对于这种查询场景的优化策略,就是下面的BloomFilter索引。

    Bloom Filter Index

    之前有篇文章《大数据去重统计之BloomFilter》,介绍过BloomFilter的原理和Java版的例子。Hive的ORC中基于此,提供了BloomFilter索引,用于性能优化。

    在建表时候,通过表参数”orc.bloom.filter.columns”=”pcid”来指定为那些字段建立BloomFilter索引,这样,在生成数据的时候,会在每个stripe中,为该字段建立BloomFilter的数据结构,当查询条件中包含对该字段的=号过滤时候,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe.

    看下面的建表语句,为pcid字段建立BloomFilter索引:

    1. CREATE TABLE lxw1234_orc2 stored AS ORC
    2. TBLPROPERTIES
    3. ('orc.compress'='SNAPPY',
    4. 'orc.create.index'='true',
    5. "orc.bloom.filter.columns"="pcid",
    6. 'orc.bloom.filter.fpp'='0.05',
    7. 'orc.stripe.size'='10485760',
    8. 'orc.row.index.stride'='10000')
    9. AS
    10. SELECT CAST(siteid AS INT) AS id,
    11. pcid
    12. FROM lxw1234_text
    13. DISTRIBUTE BY id sort BY id;

    然后执行上面的查询:

    1. SET hive.optimize.index.filter=true;
    2. SELECT COUNT(1) FROM lxw1234_orc1 WHERE id >= 0 AND id <= 1000
    3. AND pcid IN ('0005E26F0DCCDB56F9041C','A');

    orc index


    您可以关注 lxw的大数据田地 ,或者 加入邮件列表 ,随时接收博客更新的通知邮件。

     

    通过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。

    Row Group Index

    由之前的文章知道,一个ORC文件包含一个或多个stripes(groups of row data),每个stripe中包含了每个columnmin/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会失去意义。另外,这种索引通常用于数值型字段的查询过滤优化上。

    看下面的例子:

    1. CREATE TABLE lxw1234_orc2 stored AS ORC
    2. TBLPROPERTIES
    3. ('orc.compress'='SNAPPY',
    4. 'orc.create.index'='true',
    5. 'orc.bloom.filter.fpp'='0.05',
    6. 'orc.stripe.size'='10485760',
    7. 'orc.row.index.stride'='10000')
    8. AS
    9. SELECT CAST(siteid AS INT) AS id,
    10. pcid
    11. FROM lxw1234_text
    12. DISTRIBUTE BY id sort BY id;

    直接执行下面的查询(未使用索引):

    1. SELECT COUNT(1) FROM lxw1234_orc1 WHERE id >= 1382 AND id <= 1399;

    orc index

    很明显,扫描了所有记录。再使用索引查询:

    1. set hive.optimize.index.filter=true;
    2. SELECT COUNT(1) FROM lxw1234_orc1 WHERE id >= 1382 AND id <= 1399;

    orc index

    可以看到,只扫描了部分记录,即根据Row Group Index中的min/max跳过了WHERE条件中不包含的stripes,索引有效果。

    假如有下面的查询:

    1. SET hive.optimize.index.filter=true;
    2. SELECT COUNT(1) FROM lxw1234_orc1 WHERE id >= 0 AND id <= 1000
    3. AND pcid IN ('0005E26F0DCCDB56F9041C','A');

    执行的过程大概是这样的:

    先根据Row Group Index中的min/max,判断哪些stripes/file包含在内,接着逐行扫描,过滤pcid IN (‘0005E26F0DCCDB56F9041C’,’A’)的记录。

    orc index

    可以看到,没有全表扫描,跳过了一部分stripes。这样看来,如果where后面的id范围很大,完全可能会包含所有的文件,再根据pcid过滤时候,又相当于全表扫描了。

    对于这种查询场景的优化策略,就是下面的BloomFilter索引。

    Bloom Filter Index

    之前有篇文章《大数据去重统计之BloomFilter》,介绍过BloomFilter的原理和Java版的例子。Hive的ORC中基于此,提供了BloomFilter索引,用于性能优化。

    在建表时候,通过表参数”orc.bloom.filter.columns”=”pcid”来指定为那些字段建立BloomFilter索引,这样,在生成数据的时候,会在每个stripe中,为该字段建立BloomFilter的数据结构,当查询条件中包含对该字段的=号过滤时候,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe.

    看下面的建表语句,为pcid字段建立BloomFilter索引:

    1. CREATE TABLE lxw1234_orc2 stored AS ORC
    2. TBLPROPERTIES
    3. ('orc.compress'='SNAPPY',
    4. 'orc.create.index'='true',
    5. "orc.bloom.filter.columns"="pcid",
    6. 'orc.bloom.filter.fpp'='0.05',
    7. 'orc.stripe.size'='10485760',
    8. 'orc.row.index.stride'='10000')
    9. AS
    10. SELECT CAST(siteid AS INT) AS id,
    11. pcid
    12. FROM lxw1234_text
    13. DISTRIBUTE BY id sort BY id;

    然后执行上面的查询:

    1. SET hive.optimize.index.filter=true;
    2. SELECT COUNT(1) FROM lxw1234_orc1 WHERE id >= 0 AND id <= 1000
    3. AND pcid IN ('0005E26F0DCCDB56F9041C','A');

    orc index


    您可以关注 lxw的大数据田地 ,或者 加入邮件列表 ,随时接收博客更新的通知邮件。

     

    通过Row Group Index和Bloom Filter Index的双重索引优化,这条语句最终执行,只扫描了60000条记录,大大节省了MapTask的执行时间和资源。

  • 相关阅读:
    JavaScript——math对象
    JavaScript——日期相关
    JavaScript——数组与数组方法
    JavaScript——数值
    JavaScript——字符串方法
    关于CSS的一些问题(一)
    html5新增标签
    svg
    在自定义组件中使用v-model
    百度地图定位
  • 原文地址:https://www.cnblogs.com/wujin/p/6405355.html
Copyright © 2011-2022 走看看