为什么分区消除不会发生在这个查询中? [英] Why partitions elimination does not happen for this query?
问题描述
我有一个按年,月,日和小时分区的配置表。我需要运行一个查询来获取最近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屋!