自动将分区条件添加到 WHERE 子句

Posted

技术标签:

【中文标题】自动将分区条件添加到 WHERE 子句【英文标题】:Automatically add partition conditions to WHERE clause 【发布时间】:2021-12-09 18:57:07 【问题描述】:

我有一个按天和小时分区的柱状表。它存储在 S3 的 parquet 文件中,供 Athena 查询。这是创建表:

CREATE EXTERNAL TABLE foo (
  -- other columns here
  dt timestamp,
  day string,
  hour string
)
PARTITIONED BY (day string, hour string)
STORED AS parquet
LOCATION 's3://foo/foo'

S3 上的布局是这样的:

s3://foo/foo/day=2021-10-10/hh=00/*.parquet
s3://foo/foo/day=2021-10-10/hh=01/*.parquet
...etc
s3://foo/foo/day=2021-10-10/hh=23/*.parquet

所以像下面这样的查询会很快,因为它只扫描超过一小时的 parquet 文件,因为分区列被用来过滤它:

-- fast, easy to write
SELECT * FROM foo WHERE day = '2021-10-10' AND hour = '00'

但是,该表还包括完整的日期时间dt。通常我们希望为不符合天/小时边界和/或位于不同时区的范围编写查询。

例如,这将扫描所有 parquet 文件并且非常慢:

-- slow, easy to write
SELECT * FROM foo WHERE dt > '2021-10-09 23:05:00' AND dt < '2021-10-11 01:00:00'

可以通过手动计算最小包围时间段的dayhour来改进:

-- fast, painful to write
SELECT * FROM foo
WHERE
  ((day, hh) IN (('2021-10-09', '23'), ('2021-10-11', '00')) OR day = '2021-10-10')
AND
  dt > '2021-10-09 23:05:00' AND dt < '2021-10-11 01:00:00'

理想情况下,这个额外的条件可以由数据库透明地添加,以避免手动添加((day,hh) IN (...))

Athena 能以某种方式实现吗?

【问题讨论】:

我无法可视化表格结构及其列。可以添加几行示例数据吗? @TheImpaler 我进行了编辑以希望澄清这一点! 我想您可能会在 dba.stackexchange.com 上找到更好的答案 【参考方案1】:

我多次希望使用此功能,但不幸的是 Athena 不支持它。您必须同时包含 dt 列的谓词以及 dayhour 分区键。

【讨论】:

我没有足够的声望来投票,但是谢谢!

以上是关于自动将分区条件添加到 WHERE 子句的主要内容,如果未能解决你的问题,请参考以下文章

减去/添加到 Where 子句时间戳条件

自动将一些 Where 子句添加到 Linq 表达式树

在 from 子句 *and* where 子句中添加连接条件使查询更快。为啥?

向 where 子句添加条件

如何使用 AREL 执行条件 where 子句

Laravel 6:如何将多个 where 子句添加到关系中