如何使用外部表和serde优化Hive queires

Pio*_*app 1 indexing hadoop hive

第1部分:我的环境

我有以下文件上传到Hadoop:

  1. 这是纯文本
  2. 每行包含JSON,如:

{code:[int], customerId:[string], data:{[something more here]}}

  1. code 数字从1到3000,
  2. customerId 总计高达4百万,每天高达0.5万
  3. 所有文件都是gzip
  4. 在配置单元中,我使用自定义JSON serde创建了外部表(让我们称之为CUSTOMER_DATA)
  5. 每个文件中的所有文件都date存储在单独的目录中 - 我将其用作Hive表中的分区

我做的大多数查询都是过滤的date,codecustomerId.我还有第二个格式文件(我们称之为CUSTOMER_ATTRIBUTES): [customerId] [attribute_1] [attribute_2] ... [attribute_n] 它包含我所有客户的数据,所以行数高达4百万.

我按以下方式查询和过滤我的数据:

  1. 过滤date- 分区在这里使用WHERE partitionDate IN (20141020,20141020)
  2. code使用语句进行过滤,例如`WHERE code IN(1,4,5,33,6784)
  3. 加入表CUSTOMER_ATTRIBUTESCUSTOMER_DATA同条件查询像 SELECT customerId FROM CUSTOMER_DATA JOIN CUSTOMER_ATTRIBUTES ON (CUSTOMER_ATTRIBUTES.customerId=CUSTOMER_DATA.customerId) WHERE CUSTOMER_ATTRIBUTES.attribute_1=[something]

第2部分:问题

有什么有效的方法可以优化我的查询.我读到有关索引和存储桶的信息,我不知道是否可以将它们与外部表一起使用,以及它们是否会优化我的查询.

Urv*_*ida 5

搜索性能:

就考虑性能而言,内部或外部表没有区别.您可以在两者上构建索引.在大型数据集上构建索引的任何一种方法都是反直觉的.

在搜索列上存储数据会带来很多性能提升.但是,您是否可以提取数据取决于您的用例.如果可以使用代码/客户ID,您可以考虑进行更多分区(如果可能)以获得更多收益.希望您没有很多独特的代码或客户ID.

我强烈建议您远离JSON测试数据,而不是在Textual Json格式化数据上尝试这些内容.解析JSON(Text)是一个重要的性能杀手.

这些天有很多文件格式工作得很好.如果无法更改生成数据的组件,则可以使用一系列查询和表格转换为其他文件格式.这将是每个分区数据的一次性作业.之后,您的搜索查询将在较新的文件格式上运行得更快.

例如.RC配置格式是由hive支持的.如果你输出代码,customerid作为RCFILE中的单独列,则查询引擎可以完全跳过数据col,因为不匹配(1,4,5,33,6784)中的代码,从而大大减少了IO.将数据存储在RCFile中,即柱状存储将有助于您的连接.使用RCFile运行带有连接的查询时,配置单元执行引擎将只读入所需的列,再次显着减少IO.除此之外,如果您将您的列作为JOIN键的一部分进行存储,则可以提高性能.

如果你需要拥有JSON,因为嵌套数据的性质,那么我建议你看看Parquet 它会给你RCFile +二进制(avro,thrift等)的性能提升

在我的工作中,我们有两列重度嵌套的JSON数据.我们尝试将其存储为压缩文本和序列文件格式.然后,我们将复杂的嵌套JSON列拆分为较少嵌套的多列,并将一些经常搜索的键拉出到其他列中.我们将其存储为RC文件,我们在搜索时观察到的性能提升很大.右边有更多的数据突发,我们需要提高更多.在尝试了一些事情并与Cloudera家伙交谈后,只有一个很大的领域需要改进.远离JSON解析.实木复合地似乎是空闲的候选人.