Hadoop-impala十大优化之(2)—impala连接查询性能优化及最佳实践

1.1  Hadoop-impala十大优化之(2)—impala连接查询的性能优化

        涉及连接操作的查询通常需要更多的调整,而不是仅指一个表的查询。从联接查询集合查询的结果集的最大大小是所有联接表中的行数的乘积。当加入数个表有数以百万计或数十亿的行,任何错过的机会过滤结果集,或其他低效的查询,可能导致一个操作,不完成在一个实际的时间,必须被取消。

         调整Impala的最简单的方法连接查询是收集统计每个表参与联接的计算统计表,然后让Impala自动优化基于每个表的大小的查询,对每一列的不同值的数量,等等。计算统计表和连接优化了Impala1.2.2新特点。对于每个表的精确统计,在将数据加载到该表中后,发出计算统计报表,如果数据量大幅度的改变,加载数据,添加一个分区,等等。

        如果没有可用的统计信息在连接查询所有表,或者如果Impala选择连接顺序,是不是最有效的,你可以重写自动连接顺序优化通过指定straight_join关键词后立即选择关键词。在这种情况下,Impala用出现的查询指导顺序处理。

         当你使用straight_join技术,你必须手动而不是依靠Impala优化器查询表的连接。该优化使用复杂的技术来估计连接的每个阶段的结果集的大小。对于手动排序,采用这种启发式的方法开始,然后实验来微调顺序:

指定最大的表。这个表是由每个Impala节点从磁盘读取,其规模不是很大的内存使用情况的查询。

         下一步,指定最小的表。第二、第三、等表的内容都在网络上传输。要将连接查询的每个后续阶段的结果集的大小减到最小。最有可能的方法是先加入一个小的表,这样结果集仍然很小,即使随后的较大的表被处理。

         加入下一个最小的表,然后是下一个最小的,等等。

         例如,如果你有表大,中,小,微小,逻辑连接顺序尝试将是大,微小,小,中。

        术语“最大”和“最小”是指基于每个表中的行和列的数量的中间结果集的大小,是结果集的一部分。例如,如果你加入一个表的销售与另一个表的客户,查询可能会发现从100个不同的客户,共有5000采购的结果。在这种情况下,您将指定选择…从销售连接客户……,把客户放在右边,因为它在这个查询的上下文中是小的。

        impala的查询计划选择不同的技术之间进行连接查询,根据表的绝对和相对大小。广播连接是默认的,在右边的表被认为是小于左边的表,它的内容被发送到查询中涉及的所有其他节点上。另一种技术被称为一个分区的连接(不涉及到一个分区表),这是更适合于大表的大小大致相等。使用这种技术,每个表的一部分被发送到适当的其他节点,其中的行的子集可以被并行处理。广播或分区连接的选择也取决于在联接中的所有表可用的统计数据,由计算统计报表所收集的数据中的所有表。

        要查看哪些连接策略用于某个特定的查询,为查询发出一个解释语句。如果你发现一个查询使用广播连接,当你知道通过基准,一个分区的连接将是更有效的,或反之亦然,向查询添加一个提示,以指定使用精确的连接机制。在Impala的SELECT语句详见查询提示。

1.1.1  当统计数字不可用时如何处理

         如果表或列统计信息不可用,在加入一些表,impala还是重新排序表使用信息是可用的。表统计放在连接顺序的左侧,在成本递减的顺序,基于整体规模和基数。没有统计的表被视为零大小,也就是说,它们总是放在连接顺序的右边。


1.1.2  straight_join连接顺序大于其他

         如果Impala连接查询是没有效率的,过时的统计数据或意外的数据分布,你可以把impala从排序连接表采用straight_join关键词后立即选择关键词。的straight_join关键词关闭重新加入条款,impala是内部,并产生一个依赖于加入条款被有序的优化查询文本中的计划。在这种情况下,重写查询,以便最大的表在左边,其次是下一个最大的,等等,直到最小的表在右边。

         在这个例子中,从大表的子查询产生一个非常小的结果集,但表可能仍然被视为最大的连接顺序放在第一。使用straight_join最后加入条款阻止最终的表被重新排序,使其在最右边的表的连接顺序。

selectstraight_join x from medium join small join (select * from big where c1 <10) as big

  where medium.id = small.id and small.id =big.id;

1.1.3  连接顺序优化实例

        这里的实际例子从侧面证明:调整Impala的最简单的方法连接查询是收集统计每个表参与联接的计算统计表。

         这里有示例显示在表之间有10亿、2亿和100万行的连接。(在这种情况下,表没有分区和使用Parquet 格式。)小表包含从最大的一个数据子集,对加入的唯一ID列方便。最小的表只包含从其他表中的列的子集。

[localhost:21000]> create table big stored as parquet as select * from raw_data;

+----------------------------+

|summary                    |

+----------------------------+

| Inserted1000000000 row(s) |

+----------------------------+

|||Returned1 row(s) in 671.56s

[localhost:21000]> desc big;

+-----------+---------+---------+

| name      | type   | comment |

+-----------+---------+---------+

| id        | int     |        |

| val       | int    |         |

|zfill     | string  |        |

| name      | string |         |

| assertion| boolean |         |

+-----------+---------+---------+

Returned 5row(s) in 0.01s

 [localhost:21000] > create table mediumstored as parquet as select * from big limit 200 * floor(1e6);

+---------------------------+

|summary                   |

+---------------------------+

| Inserted200000000 row(s) |

+---------------------------+

|Returned 1row(s) in 138.31s

[localhost:21000]> create table small stored as parquet as select id,val,name from big whereassertion = true limit 1 * floor(1e6);

+-------------------------+

|summary                 |

+-------------------------+

| Inserted1000000 row(s) |

+-------------------------+

|Returned 1row(s) in 6.32s

        对于任何一种性能试验,使用EXPLAIN语句看到任何昂贵的查询将不进行实际运行,使冗长的解释计划包含更注重性能的细节:最有趣的计划线路以粗体突出显示,显示没有连接表统计,impala不能在处理各阶段涉及的行数的一个很好的估计,并可能坚持广播加入机制,将一张表完全复制到每个节点。

[localhost:21000]> set explain_level=verbose;

EXPLAIN_LEVELset to verbose

[localhost:21000]> explain select count(*) from big join medium where big.id = medium.id;

+----------------------------------------------------------+

| ExplainString                                          |

+----------------------------------------------------------+

| EstimatedPer-Host Requirements: Memory=2.10GB VCores=2 |

|                                                         |

| PLANFRAGMENT 0                                          |

|   PARTITION: UNPARTITIONED                               |

|                                                         |

|   6:AGGREGATE (merge finalize)                           |

|   | output: SUM(COUNT(*))                               |

|   | cardinality: 1                                      |

|   | per-host memory: unavailable                        |

|   | tuple ids: 2                                        |

|   |                                                     |

|   5:EXCHANGE                                             |

|      cardinality: 1                                      |

|      per-host memory: unavailable                        |

|      tuple ids: 2                                        |

|                                                         |

| PLANFRAGMENT 1                                          |

|   PARTITION: RANDOM                                      |

|                                                         |

|   STREAM DATA SINK                                       |

|     EXCHANGE ID: 5                                       |

|     UNPARTITIONED                                        |

|                                                         |

|   3:AGGREGATE                                            |

|   | output: COUNT(*)                                    |

|   | cardinality: 1                                      |

|   | per-host memory: 10.00MB                            |

|   | tuple ids: 2                                        |

|   |                                                     |

|   2:HASH JOIN                                            |

|   |  joinop: INNER JOIN (BROADCAST)                    |

|   | hash predicates:                                    |

|   |   big.id = medium.id                                |

|  |  cardinality: unavailable                            |

|   | per-host memory: 2.00GB                             |

|   | tuple ids: 0 1                                      |

|   |                                                     |

|   |----4:EXCHANGE                                        |

|   |      cardinality: unavailable                       |

|   |      per-host memory: 0B                            |

|   |      tuple ids: 1                                   |

|   |                                                     |

|   0:SCAN HDFS                                            |

|     table=join_order.big #partitions=1/1 size=23.12GB   |

|     table stats: unavailable                            |

|     column stats: unavailable                           |

|     cardinality: unavailable                            |

|      per-host memory: 88.00MB                            |

|      tuple ids: 0                                        |

|                                                         |

| PLANFRAGMENT 2                                          |

|   PARTITION: RANDOM                                      |

|                                                         |

|   STREAM DATA SINK                                       |

|     EXCHANGE ID: 4                                       |

|     UNPARTITIONED                                        |

|                                                         |

|   1:SCAN HDFS                                            |

|     table=join_order.medium #partitions=1/1 size=4.62GB |

|     table stats: unavailable                            |

|     column stats: unavailable                           |

|      cardinality:unavailable                            |

|      per-host memory: 88.00MB                            |

|      tuple ids: 1                                        |

+----------------------------------------------------------+

Returned 64row(s) in 0.04s

收集所有表的统计数据是简单的,一个计算每表的计算统计语句:

[localhost:21000]> compute stats small;

+-----------------------------------------+

|summary                                 |

+-----------------------------------------+

| Updated 1partition(s) and 3 column(s). |

+-----------------------------------------+

|Returned 1row(s) in 4.26s

[localhost:21000]> compute stats medium;

+-----------------------------------------+

|summary                                 |

+-----------------------------------------+

| Updated 1partition(s) and 5 column(s). |

+-----------------------------------------+

|Returned 1row(s) in 42.11s

[localhost:21000]> compute stats big;

+-----------------------------------------+

|summary                                 |

+-----------------------------------------+

| Updated 1partition(s) and 5 column(s). |

+-----------------------------------------+

|Returned 1row(s) in 165.44s

使用统计信息,Impala可以选择更有效的连接顺序而不是从左到右的顺序查询中的表,并可选择广播或分区的基础上加入整体尺寸和表中的行数的策略:

[localhost:21000]> explain select count(*) from medium join big where big.id = medium.id;

Query:explain select count(*) from medium join big where big.id = medium.id

+-----------------------------------------------------------+

| ExplainString                                            |

+-----------------------------------------------------------+

| EstimatedPer-Host Requirements: Memory=937.23MB VCores=2 |

|                                                           |

| PLANFRAGMENT 0                                           |

|   PARTITION: UNPARTITIONED                                |

|                                                          |

|   6:AGGREGATE (merge finalize)                            |

|   | output: SUM(COUNT(*))                                |

|   | cardinality: 1                                       |

|   | per-host memory: unavailable                         |

|   | tuple ids: 2                                         |

|   |                                                      |

|   5:EXCHANGE                                              |

|      cardinality: 1                                       |

|      per-host memory: unavailable                         |

|      tuple ids: 2                                         |

|                                                          |

| PLANFRAGMENT 1                                           |

|   PARTITION: RANDOM                                       |

|                                                          |

|   STREAM DATA SINK                                        |

|     EXCHANGE ID: 5                                        |

|     UNPARTITIONED                                         |

|                                                           |

|   3:AGGREGATE                                             |

|   | output: COUNT(*)                                     |

|   | cardinality: 1                                       |

|   | per-host memory: 10.00MB                             |

|   | tuple ids: 2                                         |

|   |                                                      |

|   2:HASH JOIN                                             |

|   | join op: INNER JOIN (BROADCAST)                      |

|   | hash predicates:                                     |

|   |   big.id = medium.id                                 |

|   | cardinality: 1443004441                              |

|   | per-host memory: 839.23MB                            |

|   | tuple ids: 1 0                                       |

|   |                                                      |

|   |----4:EXCHANGE                                         |

|   |      cardinality: 200000000                          |

|   |      per-host memory: 0B                             |

|   |      tuple ids: 0                                    |

|   |                                                      |

|   1:SCAN HDFS                                             |

|      table=join_order.big #partitions=1/1size=23.12GB    |

|      table stats: 1000000000 rows total                   |

|      column stats: all                                    |

|      cardinality: 1000000000                              |

|      per-host memory: 88.00MB                             |

|      tuple ids: 1                                         |

|                                                          |

| PLANFRAGMENT 2                                           |

|   PARTITION: RANDOM                                       |

|                                                          |

|   STREAM DATA SINK                                        |

|     EXCHANGE ID: 4                                        |

|     UNPARTITIONED                                         |

|                                                          |

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24179204/viewspace-2129797/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/24179204/viewspace-2129797/

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值