为什么分区消除不会发生在这个查询中? [英] Why partitions elimination does not happen for this query?

查看:130
本文介绍了为什么分区消除不会发生在这个查询中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个按年,月,日和小时分区的配置表。我需要运行一个查询来获取最近7天的数据。这在 Hive 0.14.0.2.2.4.2-2 中。我的查询目前看起来像这样:

 来自table_name的SELECT COUNT(column_name)
年份> =年份(date_sub (from_unixtime(unix_timestamp()),7))
AND month> = month(date_sub(from_unixtime(unix_timestamp()),7))
AND day> = day(date_sub(from_unixtime(unix_timestamp ()),7));

这需要很长时间。当我将上面的实际数字替换为这样的内容时:

 来自table_name 
的SELECT COUNT(column_name) > = 2017
与月份> = 2
与日期> = 13



它在几分钟内完成。有什么方法可以改变上面的脚本,以便实际上只包含查询中的数字而不是函数?



我尝试使用 set 类似:

  set yearLimit = year(date_sub(from_unixtime(unix_timestamp()),7)); 

从table_name
where year> = $ {hiveconf:yearLimit}
AND month> = month(date_sub(from_unixtime(unix_timestamp())中选择COUNT(column_name) 7))
和day> = day(date_sub(from_unixtime(unix_timestamp()),7));

但这并不能解决问题。

解决方案

解决方案



  select count(column_name)

from table_name

where year> = year(date_sub(current_date,7))
and month> = month(date_sub( current_date,7))
和day> = day(date_sub(current_date,7))
;



原始查询出错了吗?



< blockquote>

unix_timestamp()
$ b 获取当前Unix时间戳,以秒为单位。这个函数不是
确定性的,它的值对于查询
执行的范围是不固定的,因此阻止了适当的查询优化 - 这个
从2.0开始被弃用,以支持CURRENT_TIMESTAMP常量。


https:/ /cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF


(我刚换了文档有点: - )



由于unix_timestamp()值在执行过程中可能会发生变化,因此应对每行评估表达式,因此防止分区消除。



为什么使用 SET 不起作用?



set 不过是一种文本替换机制。

set

发生的唯一情况是变量是b eing分配了一个文本

在执行查询之前,变量占位符( $ {hiveconf:...} )被替换为指定的文本

只有这样才能解析和执行查询。

 分群>设置= sele; 
hive>设置b = ct 1+;
hive>设置c = 1;
hive> $ {hiveconf:一个} $ {hiveconf:B} $ {hiveconf:C};
OK
2






演示



  create table table_name(column_name int)分区为(年份int,月份int,日期int); 

set hive.exec.dynamic.partition.mode = nonstrict;


插入table_name分区(年,月,日)

select pos
,year(dt)
,month(dt )
,day(dt)

from(select pe.pos
,date_sub(current_date,pe.pos)as dt

from(select 1)x
横向视图posexplode(split(space(99),''))pe
)t
;






 解释(date_sub(from_unixtime(unix_timestamp()),7)依赖关系

select table count(column_name)

from table_name

where year> = year )
和month> = month(date_sub(from_unixtime(unix_timestamp()),7))
和day> = day(date_sub(from_unixtime(unix_timestamp()),7))
;







{input_partitions :[{ 分区名 : 默认@ table_name的@年= 2016 /月= 11 /天= 14 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 11 /天= 15\" } { 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 16},{ 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 17},{ 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 18},{ 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 19},{分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 20 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 11 /天= 21 },{ 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 22},{ 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 23},{ 分区名:默认@ TABLE_NAME @年= 2016 /月= 11 /天= 24 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 11 /天= 25 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 11 /天= 26 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 11 /天= 27\" } { 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 28},{ 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 29},{ 分区名: 默认@ table_name的@年= 2016 /月= 11 /天= 30},{ 分区名: 默认@ table_name的@年= 2016 /月= 12 /天= 1},{分区名: 默认@ table_name的@年= 2016 /月= 12 /天= 10 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 11 },{ 分区名: 默认@ table_name的@年= 2016 /月= 12 /天= 12},{ 分区名: 默认@ table_name的@年= 2016 /月= 12 /天= 13},{ 分区名:默认@ TABLE_NAME @年= 2016 /月= 12 /天= 14 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 15 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 16 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 17 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 18 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 19 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 2 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 20 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 21 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 22 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 23 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 24 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 25 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 26 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 27 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 28 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 29 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 3 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 30 },{ 分区名 : 默认@ table_name的@年= 2016 /月= 12 /天= 31 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 4 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 5\" },{ 分区名:默认@ table_name的@年= 2016 /月= 1 2 /天= 6 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 7 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 8 },{ 分区名 : 默认@ TABLE_NAME @年= 2016 /月= 12 /天= 9 },{ 分区名 : 默认@ TABLE_NAME @年= 2017 /月= 1 /天= 1 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 10 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 11\" },{ 分区名: 默认@ table_name的@年= 2017年/月= 1 /天= 12},{ 分区名: 默认@ table_name的@年= 2017年/月= 1 /天= 13}, { 分区名: 默认@ table_name的@年= 2017年/月= 1 /天= 14},{ 分区名: 默认@ table_name的@年= 2017年/月= 1 /天= 15},{分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 16 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 17 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 18},{ 分区名: 默认@ table_name的@年= 2017年/月= 1 /天= 19},{ 分区名:默认@ TABLE_NAME @年= 2017年/月= 1 /天= 2 },{ 分区名 : 默认@ table_名@年= 2017年/月= 1 /天= 20 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 21 },{ 分区名 : 默认@ TABLE_NAME @年= 2017年/月= 1 /天= 22 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 23 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 24 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 25 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 26 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 27 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1次/天= 28 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 29 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 3 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 30 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 31 },{ 分区名 : 默认@ TABLE_NAME @年= 2017 /月= 1 /天= 4 },{ 分区名 : 默认@ TABLE_NAME @年= 2017 /月= 1 /天= 5\" },{ 分区名: 默认@ table_name的@年= 2017年/月= 1 /天= 6},{partitionN AME : 默认@ table_name的@年= 2017年/月= 1 /天= 7 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 8 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 1 /天= 9},{ 分区名: 默认@ table_name的@年= 2017年/月= 2 /天= 1},{ 分区名:默认@ TABLE_NAME @年= 2017年/月= 2 /天= 10 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 11 },{ 分区名 : 默认@ TABLE_NAME @年= 2017年/月= 2 /天= 12 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 13 },{ 分区名 : 默认@ TABLE_NAME @年= 2017年/月= 2 /天= 14 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 15 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 16 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 17 },{ 分区名 : 默认@ table_name的@年= 2017年/一个月= 2 /天= 18 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 19 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 2 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 / DA Y = 20 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 21 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 3 },{ 分区名 : 默认@ TABLE_NAME @年= 2017 /月= 2 /天= 4 },{ 分区名 : 默认@ TABLE_NAME @年= 2017 /月= 2 /天= 5\" },{ 分区名: 默认@ TABLE_NAME @年= 2017 /月= 2 /天= 6},{ 分区名: 默认@ TABLE_NAME @年= 2017 /月= 2 /天= 7}, { 分区名: 默认@ TABLE_NAME @年= 2017 /月= 2 /天= 8},{ 分区名: 默认@ TABLE_NAME @年= 2017 /月= 2 /天= 9}], input_tables:[{tablename:default @ table_name,tabletype:MANAGED_TABLE}]}



 解释依赖关系

从表名

中选择count(column_name)


where year> = year(date_sub(current_date (date_sub(current_date,7))
和day> = day(date_sub(current_date,7))
;




{input_partitions:[{partitionName:default @ TABLE_NAME @年= 2017年/月= 2 /天= 14 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 15 },{ 分区名 : 默认@ TABLE_NAME @年= 2017年/月= 2 /天= 16 },{ 分区名 : 默认@ table_name的@年= 2017年/月= 2 /天= 17 },{ 分区名 : 默认@ table_name的@年= 2017 /月= 2 /天= 18 },{ 分区名 : 默认@ table_name的@年= 2017 /月= 2 /天= 19 },{ 分区名 : 默认@ table_name的@年= 2017 /一个月= 2 /天= 20 },{ 分区名 : 默认@ TABLE_NAME @年= 2017 /月= 2 /天= 21 }], input_tables :[{ 表名 : 默认@表格名 ,tabletype:MANAGED_TABLE}]}



I have a hive table which is partitioned by year, month, day and hour. I need to run a query against it to fetch the last 7 days data. This is in Hive 0.14.0.2.2.4.2-2. My query currently looks like this :

SELECT COUNT(column_name) from table_name 
where year >= year(date_sub(from_unixtime(unix_timestamp()), 7)) 
AND month >= month(date_sub(from_unixtime(unix_timestamp()), 7)) 
AND day >= day(date_sub(from_unixtime(unix_timestamp()), 7));

This takes a very long time. When I substitute the actual numbers for the above say something like :

SELECT COUNT(column_name) from table_name 
where year >= 2017
AND month >= 2
AND day >= 13

it finishes in a few minutes. Is there any way to change the above script so that is actually includes just the numbers in the query instead of the functions?

I tried using set like:

set yearLimit = year(date_sub(from_unixtime(unix_timestamp()), 7));

SELECT COUNT(column_name) from table_name 
where year >= ${hiveconf:yearLimit}
AND month >= month(date_sub(from_unixtime(unix_timestamp()), 7)) 
AND day >= day(date_sub(from_unixtime(unix_timestamp()), 7));

but this does not solve the issue.

解决方案

Solution

select      count (column_name) 

from        table_name 

where       year  >= year  (date_sub (current_date,7)) 
        and month >= month (date_sub (current_date,7)) 
        and day   >= day   (date_sub (current_date,7))
;

What went wrong with the original query?

unix_timestamp()

Gets current Unix timestamp in seconds. This function is not deterministic and its value is not fixed for the scope of a query execution, therefore prevents proper optimization of queries - this has been deprecated since 2.0 in favour of CURRENT_TIMESTAMP constant.

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF

(I've just changed the documentation a little bit :-))

Since unix_timestamp() values might change during the execution, the expression should be evaluated for each row, therefore preventing partitions elimination.

Why using SET did not work?

set is nothing but a text replacement mechanism.
Nothing is being computed during the set.
The only thing that happens is that variables are being assigned a text.
Before the query is being executed the variables place holders (${hiveconf:...}) are being replaced with the assigned text.
Only then the query is being parsed and executed.

hive> set a=sele;
hive> set b=ct 1+;
hive> set c=1;
hive> ${hiveconf:a}${hiveconf:b}${hiveconf:c};
OK
2


Demo

create table table_name (column_name int) partitioned by (year int,month int,day int);

set hive.exec.dynamic.partition.mode=nonstrict;


insert into table_name partition (year,month,day) 

select  pos
       ,year(dt)
       ,month(dt)
       ,day(dt) 

from   (select  pe.pos
               ,date_sub (current_date,pe.pos) as dt

        from    (select 1) x 
                lateral view posexplode (split (space (99),' ')) pe
        ) t
;


explain dependency

select      count (column_name) 

from        table_name 

where       year  >= year  (date_sub (from_unixtime (unix_timestamp ()),7)) 
        and month >= month (date_sub (from_unixtime (unix_timestamp ()),7)) 
        and day   >= day   (date_sub (from_unixtime (unix_timestamp ()),7))
;


{"input_partitions":[{"partitionName":"default@table_name@year=2016/month=11/day=14"},{"partitionName":"default@table_name@year=2016/month=11/day=15"},{"partitionName":"default@table_name@year=2016/month=11/day=16"},{"partitionName":"default@table_name@year=2016/month=11/day=17"},{"partitionName":"default@table_name@year=2016/month=11/day=18"},{"partitionName":"default@table_name@year=2016/month=11/day=19"},{"partitionName":"default@table_name@year=2016/month=11/day=20"},{"partitionName":"default@table_name@year=2016/month=11/day=21"},{"partitionName":"default@table_name@year=2016/month=11/day=22"},{"partitionName":"default@table_name@year=2016/month=11/day=23"},{"partitionName":"default@table_name@year=2016/month=11/day=24"},{"partitionName":"default@table_name@year=2016/month=11/day=25"},{"partitionName":"default@table_name@year=2016/month=11/day=26"},{"partitionName":"default@table_name@year=2016/month=11/day=27"},{"partitionName":"default@table_name@year=2016/month=11/day=28"},{"partitionName":"default@table_name@year=2016/month=11/day=29"},{"partitionName":"default@table_name@year=2016/month=11/day=30"},{"partitionName":"default@table_name@year=2016/month=12/day=1"},{"partitionName":"default@table_name@year=2016/month=12/day=10"},{"partitionName":"default@table_name@year=2016/month=12/day=11"},{"partitionName":"default@table_name@year=2016/month=12/day=12"},{"partitionName":"default@table_name@year=2016/month=12/day=13"},{"partitionName":"default@table_name@year=2016/month=12/day=14"},{"partitionName":"default@table_name@year=2016/month=12/day=15"},{"partitionName":"default@table_name@year=2016/month=12/day=16"},{"partitionName":"default@table_name@year=2016/month=12/day=17"},{"partitionName":"default@table_name@year=2016/month=12/day=18"},{"partitionName":"default@table_name@year=2016/month=12/day=19"},{"partitionName":"default@table_name@year=2016/month=12/day=2"},{"partitionName":"default@table_name@year=2016/month=12/day=20"},{"partitionName":"default@table_name@year=2016/month=12/day=21"},{"partitionName":"default@table_name@year=2016/month=12/day=22"},{"partitionName":"default@table_name@year=2016/month=12/day=23"},{"partitionName":"default@table_name@year=2016/month=12/day=24"},{"partitionName":"default@table_name@year=2016/month=12/day=25"},{"partitionName":"default@table_name@year=2016/month=12/day=26"},{"partitionName":"default@table_name@year=2016/month=12/day=27"},{"partitionName":"default@table_name@year=2016/month=12/day=28"},{"partitionName":"default@table_name@year=2016/month=12/day=29"},{"partitionName":"default@table_name@year=2016/month=12/day=3"},{"partitionName":"default@table_name@year=2016/month=12/day=30"},{"partitionName":"default@table_name@year=2016/month=12/day=31"},{"partitionName":"default@table_name@year=2016/month=12/day=4"},{"partitionName":"default@table_name@year=2016/month=12/day=5"},{"partitionName":"default@table_name@year=2016/month=12/day=6"},{"partitionName":"default@table_name@year=2016/month=12/day=7"},{"partitionName":"default@table_name@year=2016/month=12/day=8"},{"partitionName":"default@table_name@year=2016/month=12/day=9"},{"partitionName":"default@table_name@year=2017/month=1/day=1"},{"partitionName":"default@table_name@year=2017/month=1/day=10"},{"partitionName":"default@table_name@year=2017/month=1/day=11"},{"partitionName":"default@table_name@year=2017/month=1/day=12"},{"partitionName":"default@table_name@year=2017/month=1/day=13"},{"partitionName":"default@table_name@year=2017/month=1/day=14"},{"partitionName":"default@table_name@year=2017/month=1/day=15"},{"partitionName":"default@table_name@year=2017/month=1/day=16"},{"partitionName":"default@table_name@year=2017/month=1/day=17"},{"partitionName":"default@table_name@year=2017/month=1/day=18"},{"partitionName":"default@table_name@year=2017/month=1/day=19"},{"partitionName":"default@table_name@year=2017/month=1/day=2"},{"partitionName":"default@table_name@year=2017/month=1/day=20"},{"partitionName":"default@table_name@year=2017/month=1/day=21"},{"partitionName":"default@table_name@year=2017/month=1/day=22"},{"partitionName":"default@table_name@year=2017/month=1/day=23"},{"partitionName":"default@table_name@year=2017/month=1/day=24"},{"partitionName":"default@table_name@year=2017/month=1/day=25"},{"partitionName":"default@table_name@year=2017/month=1/day=26"},{"partitionName":"default@table_name@year=2017/month=1/day=27"},{"partitionName":"default@table_name@year=2017/month=1/day=28"},{"partitionName":"default@table_name@year=2017/month=1/day=29"},{"partitionName":"default@table_name@year=2017/month=1/day=3"},{"partitionName":"default@table_name@year=2017/month=1/day=30"},{"partitionName":"default@table_name@year=2017/month=1/day=31"},{"partitionName":"default@table_name@year=2017/month=1/day=4"},{"partitionName":"default@table_name@year=2017/month=1/day=5"},{"partitionName":"default@table_name@year=2017/month=1/day=6"},{"partitionName":"default@table_name@year=2017/month=1/day=7"},{"partitionName":"default@table_name@year=2017/month=1/day=8"},{"partitionName":"default@table_name@year=2017/month=1/day=9"},{"partitionName":"default@table_name@year=2017/month=2/day=1"},{"partitionName":"default@table_name@year=2017/month=2/day=10"},{"partitionName":"default@table_name@year=2017/month=2/day=11"},{"partitionName":"default@table_name@year=2017/month=2/day=12"},{"partitionName":"default@table_name@year=2017/month=2/day=13"},{"partitionName":"default@table_name@year=2017/month=2/day=14"},{"partitionName":"default@table_name@year=2017/month=2/day=15"},{"partitionName":"default@table_name@year=2017/month=2/day=16"},{"partitionName":"default@table_name@year=2017/month=2/day=17"},{"partitionName":"default@table_name@year=2017/month=2/day=18"},{"partitionName":"default@table_name@year=2017/month=2/day=19"},{"partitionName":"default@table_name@year=2017/month=2/day=2"},{"partitionName":"default@table_name@year=2017/month=2/day=20"},{"partitionName":"default@table_name@year=2017/month=2/day=21"},{"partitionName":"default@table_name@year=2017/month=2/day=3"},{"partitionName":"default@table_name@year=2017/month=2/day=4"},{"partitionName":"default@table_name@year=2017/month=2/day=5"},{"partitionName":"default@table_name@year=2017/month=2/day=6"},{"partitionName":"default@table_name@year=2017/month=2/day=7"},{"partitionName":"default@table_name@year=2017/month=2/day=8"},{"partitionName":"default@table_name@year=2017/month=2/day=9"}],"input_tables":[{"tablename":"default@table_name","tabletype":"MANAGED_TABLE"}]}

explain dependency

select      count (column_name) 

from        table_name 

where       year  >= year  (date_sub (current_date,7)) 
        and month >= month (date_sub (current_date,7)) 
        and day   >= day   (date_sub (current_date,7))
;

{"input_partitions":[{"partitionName":"default@table_name@year=2017/month=2/day=14"},{"partitionName":"default@table_name@year=2017/month=2/day=15"},{"partitionName":"default@table_name@year=2017/month=2/day=16"},{"partitionName":"default@table_name@year=2017/month=2/day=17"},{"partitionName":"default@table_name@year=2017/month=2/day=18"},{"partitionName":"default@table_name@year=2017/month=2/day=19"},{"partitionName":"default@table_name@year=2017/month=2/day=20"},{"partitionName":"default@table_name@year=2017/month=2/day=21"}],"input_tables":[{"tablename":"default@table_name","tabletype":"MANAGED_TABLE"}]}

这篇关于为什么分区消除不会发生在这个查询中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆