让我举例说明。我们有一个包含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运算符的数量。我正在处理数十亿条记录的表,对查询的任何优化对我来说都是个好消息。
我应该如何解释“解释”命令中选择的运算符数量的减少?
谢谢
计划中的数字取自陈旧或根本没有的统计数据。如果缺少统计信息,则估计行数,并且此估计不准确。 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;
set hive.stats.fetch.partition.stats=true;