sql—向where子句添加冗余的true条件如何提高配置单元查询性能?

7hiiyaii  于 2021-06-24  发布在  Hive
关注(0)|答案(1)|浏览(251)

让我举个例子来说明。我们有一个表,有一百万条记录,有几列。注意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"]

优化器报告为select返回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操作符的数量。我处理的表有几十亿条记录,任何查询优化对我来说都是好消息。
如何解释explain命令中select运算符数的减少?
这是否意味着添加一个dummy where条件(用explain命令显示缩减)可以潜在地提高查询性能?
除了可读性和样式之外,在where子句中添加这样的伪条件还有什么坏处吗?它真的会影响查询性能吗?
谢谢

ddrv8njm

ddrv8njm1#

计划中的数字是从统计数字中提取出来的,这些数字可能是陈旧的,也可能根本不存在。如果缺少统计信息,则估计行数,并且此估计不准确。Hive只是估计所有的条件都是有选择性的。
尝试收集列的统计数据并再次检查计划,数字可能会改变。在执行explain之前,还要确保statistics usage已打开:

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,例如,如果配置单元错误地估计了行数,并且将对内存中不适合的表运行map join,那么它将导致oom,或者将生成次优计划。
在您的案例中,虚拟条件并不能真正提高性能,只要检查两个查询的执行时间,您就会看到。

相关问题