过滤按日期一大桌(Filtering a large table by date)

2019-10-24 01:53发布

我有一个表,VISIT_INFO,这些列:

pers_key - unique identifyer for each person
pers_name - name of person
visit_date - date at which they visited a business

而另一张表,VALID_DATES,这些列:

condition - string
start_date - date
end_date - date 

目前,我有以下查询:

select pers_key, pers_name from VISIT_INFO a
CROSS JOIN
(select start_date, end_date from VALID_DATES where condition = 'condition1') b
WHERE (a.visit_date >= b.start_date and a.visit_date <= b.end_date)
GROUP BY a.pers_key

所以,“条件1”都有特定的起始日期日期和结束日期。 我需要过滤VISIT_INFO的访问的是两个日期之间。 我不知道是否有这样做更有效的方式。 从我目前的理解,它目前已完成整个表去(百万行)并添加起始日期日期和结束日期到每一行。 然后,它必须再次和测试要经过的每一行对WHERE条件?

我问这个,因为当我删除交叉连接和硬编码为条件1的起始日期日期和结束日期,这需要相当的时间更少。 我试图避免在硬编码的日期,因为它会导致严重的单调乏味的道路。

因此,要重申的是,有没有更好的办法在VALID_DATES具体日期过滤VISIT_INFO?

编辑:我才意识到我留下了非常巨大的信息块,是,这是所有在HIVE。 所以EXISTS并加入对(B之间a和c)都出了问题。

Answer 1:

怎么样:

SELECT DISTINCT pers_key, pers_name
FROM visit_info
WHERE EXISTS
(
    SELECT 1
    FROM valid_dates
    WHERE condition = 'condition1'
    AND visit_date BETWEEN start_date AND end_date
);



Answer 2:

with dt as (select start_date, end_date from VALID_DATES where condition = 'condition1')
select a.pers_key, a.pers_name 
from VISIT_INFO a
JOIN dt on a.visit_date between dt.start_date and dt.end_date
GROUP BY a.pers_key


Answer 3:

尝试exists的版本绝对是一个可能性。 但是,你可能会关闭扩展更好VALID_DATES表,所以每个日期一行。

随后,查询:

select vi.*
from VISIT_INFO vi JOIN
     VALID_DATES_expanded vde
     ON vi.visit_date = vde.valid_date
where vde.condition = 'condition1';

可以对使用索引VISIT_INFO(visit_date)和上VALID_DATES_expanded(condition, valid_date) 这很可能是最快的方法来解决这个问题,如果VISIT_INFO是非常大的,相对较少的行正在被查询选择。



文章来源: Filtering a large table by date