首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调优使用基础HBase表的Hive查询

调优使用基础HBase表的Hive查询
EN

Stack Overflow用户
提问于 2015-05-06 10:56:41
回答 1查看 6.7K关注 0票数 9

我在Hbase中有一个表,比方说"tbl“,我想使用Hive查询它。因此,我将表映射为单元,如下所示:

代码语言:javascript
复制
CREATE EXTERNAL TABLE tbl(id string, data map<string,string>)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,data:")
TBLPROPERTIES("hbase.table.name" = "tbl");

查询如下:

代码语言:javascript
复制
select * from tbl", "select id from tbl", "select id, data
from tbl

真的很快。

但是像这样的查询

代码语言:javascript
复制
select id from tbl where substr(id, 0, 5) = "12345"

select id from tbl where data["777"] IS NOT NULL 

都非常慢。

相反,当从Hbase外壳运行时:

代码语言:javascript
复制
"scan 'tbl', {
COLUMNS=>'data', STARTROW='12345', ENDROW='12346'}" or
"scan 'tbl', { COLUMNS=>'data', "FILTER" =>
FilterList.new([qualifierFilter('777')])}"

闪电太快了!

当我查看作业跟踪器上的hive生成的映射作业时,我发现"map.input.records“对Hbase表中的所有项进行了计数,这意味着作业在启动任何映射器之前就会进行完整的表扫描!此外,我怀疑它在执行之前将所有数据从Hbase表复制到hdfs到mapper输入文件夹。

因此,我的问题是-为什么用于hive的hbase存储处理程序不将hive查询转换为适当的hbase函数?为什么它扫描所有记录,然后使用"where“子句对它们进行分割?如何改进呢?

任何提高Hive查询性能的建议(映射到HBase表)。

我们可以在HBase表上创建辅助索引吗?

我们正在使用HBase和Hive集成,并试图优化Hive查询的性能。

EN

回答 1

Stack Overflow用户

发布于 2015-05-06 20:24:33

很多问题!,我会尽力回答所有的问题,并给你一些表演技巧:

数据不会被复制到HDFS,但是由HIVE生成的mapreduce作业将把它们的中间数据存储在HDFS中。

HBase (更多信息)不支持辅助索引或替代查询路径。

Hive将将所有内容转换为需要时间来分发和初始化的MapReduce作业,如果您有非常少的行,那么Hbase shell中的简单扫描操作可能比Hive查询快,但是在大型数据集中,必须在数据节点之间分配作业。

当从查询中提取开始和停止行键时,Hive HBase处理程序做得不是很好,像substr(id, 0, 5) = "12345"这样的查询不会使用开始和停止行键。

在执行查询之前,运行一个filterExpr:命令并检查filterExpr:部件,如果找不到它,查询将执行完整的表扫描。另外,Filter Operator:中的所有表示都将转换为审批过滤器。

代码语言:javascript
复制
EXPLAIN SELECT * FROM tbl WHERE (id>='12345') AND (id<'12346')
STAGE PLANS:
  Stage: Stage-1
    Map Reduce
      Alias -> Map Operator Tree:
        tbl 
          TableScan
            alias: tbl 
            filterExpr:
                expr: ((id>= '12345') and (id < '12346'))
                type: boolean
            Filter Operator
                ....

幸运的是,有一种简单的方法可以确保在查找行键前缀时使用开始和停止行键,只需将substr(id, 0, 5) = "12345"转换为一个简单的查询:id>="12345" AND id<"12346",它将由处理程序检测到,并将开始和停止行键提供给扫描(12345,12346)。

现在,为了加快查询速度,这里有一些提示:

  • 确保将以下属性设置为利用批处理来减少RPC调用的次数(该数量取决于列的大小) SET hbase.scan.cache=10000; SET hbase.client.scanner.cache=10000;
  • 确保将下列属性设置为在任务跟踪器中运行分布式作业,而不是运行本地作业。 SET mapred.job.tracker=[YOUR_JOB_TRACKER]:8021; SET hbase.zookeeper.quorum=[ZOOKEEPER_NODE_1],[ZOOKEEPER_NODE_2],[ZOOKEEPER_NODE_3];
  • 将SELECT语句的列数量减至最低。试着不做SELECT *
  • 每当您想要使用开始和停止行键来防止全表扫描时,始终提供key>=xkey<y表达式(不要使用中间操作符)
  • 始终在执行查询之前先对其进行EXPLAIN SELECT
票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30074734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档