【问题标题】:How adding redundant true conditions to where clause improves the Hive query performance?向 where 子句添加冗余 true 条件如何提高 Hive 查询性能?
【发布时间】:2020-09-22 05:59:08
【问题描述】:

让我用一个例子来演示。我们有一个包含 100 万条记录和几列的表。注意 where 子句中的 dt 条件。

create table tbl as
select * from some_table
where dt > '20200601'
limit 1000000;

现在,如果我使用 Hive explain 命令获取示例查询的执行计划,我会得到以下结果:

explain
select id from tbl
where 
    id > 1000; 

Stage-0
  Fetch Operator
    limit:-1
    Stage-1
      Map 1
      File Output Operator [FS_3]
        Select Operator [SEL_2] (rows=333333 width=196)
          Output:["_col0"]
          Filter Operator [FIL_4] (rows=333333 width=196)
            predicate:(rid > 1000L)
            TableScan [TS_0] (rows=1000000 width=196)
              user@tbl,tbl, ACID table,Tbl:COMPLETE,Col:NONE,Output:["id"]

优化器报告返回 333k ​​条记录供选择。如果我在另一列上添加另一个 Where 条件,无论如何我知道这将是正确的,优化器会为 SELECT 查询报告小得多的数字。

explain
select id from tbl
where 
    id > 1000; 
    AND dt > '20200601';

Stage-0
  Fetch Operator
    limit:-1
    Stage-1
      Map 1
      File Output Operator [FS_3]
        Select Operator [SEL_2] (rows=111111 width=196)
          Output:["_col0"]
          Filter Operator [FIL_4] (rows=111111 width=196)
            predicate:((id > 1000L) and (dt > '20200601'))
            TableScan [TS_0] (rows=1000000 width=196)
              user@tbl,tbl, ACID table,Tbl:COMPLETE,Col:NONE,Output:["id","dt"]

对于我在工作中日常使用的查询,我测试了这种情况,并且经常(并非总是)向 Where 子句添加更多条件会减少执行计划中 Select 运算符的数量. 我使用数十亿条记录的表,任何查询优化对我来说都是好消息。

我应该如何解释解释命令中选择运算符数量的减少?

  • 这是否意味着添加一个虚拟 where 条件(显示 使用解释命令减少)可以潜在地改进查询 表现?
  • 除了可读性和风格,还有什么 将此类虚拟条件添加到 Where 子句的缺点,可以吗? 真的会影响查询性能吗?

谢谢

【问题讨论】:

    标签: sql hive hiveql query-performance sql-execution-plan


    【解决方案1】:

    计划中的数据取自统计数据,这些数据可能过时或根本不存在。如果没有统计信息,则估计行数,并且该估计不准确。 Hive 只是估计所有 WHERE 条件都是选择性的。

    尝试gather statistics for COLUMNS并再次检查计划,数字可能会改变。 还要确保在执行 EXPLAIN 之前打开统计使用情况:

    set hive.cbo.enable=true;
    set hive.compute.query.using.stats=true;
    set hive.stats.fetch.column.stats=true;    --this can be expensive
    set hive.stats.fetch.partition.stats=true; --this can be expensive
    

    无论如何,计划中的这些数字是基于统计数据和文件大小的估计,是估计的平均记录大小,而不是实际计数,因此它们很少是 100% 准确的。在这种情况下,文件可以被压缩并且压缩率也被估计。

    在您的简单查询中,估计的行数不会影响查询 DAG 和性能。

    统计信息可能会影响复杂查询的 DAG,例如,如果 Hive 错误地估计了行数并且将对不适合内存的表运行 map-join,则会导致 OOM,或者会生成次优计划。

    在您的情况下,虚拟条件并没有真正提高性能,只需检查两个查询的执行时间,您就会看到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 2018-11-08
      • 2020-02-12
      • 1970-01-01
      • 1970-01-01
      • 2014-06-11
      相关资源
      最近更新 更多