我有一个由镶木地板文件组成的AWS S3数据湖, struct 如下:

s3://bucket/device/table_x/year=2000/month=01/day=02/xyz.parquet

我的目标是使用AWS Athena来查询数据,以便在Grafana仪表板上显示.我面临的挑战是,为了在利用分区的同时创建任意时间段的动态面板,我需要找到一种方法,将数据限制在WHERE分区中的相关时间段,但这样做的方式可以跨年、跨月、跨天工作,而不必根据查询构造SQL语句.

我现在最好的建议是在Query下面,这应该是可行的--但它很复杂.对于这样的声明,有没有推荐的最佳实践?

SELECT
    Count(a1) as AVG_a1                 
FROM
    tbl_11111111_a
WHERE
    (
        -- Same year, same month
        (year = 'START_YEAR' AND month = 'START_MONTH' AND day BETWEEN 'START_DAY' AND 'END_DAY')
        OR
        -- Same year, different months
        (year = 'START_YEAR' AND month = 'START_MONTH' AND day >= 'START_DAY')
        OR
        (year = 'START_YEAR' AND month > 'START_MONTH' AND month < 'END_MONTH' AND day BETWEEN '01' AND '31')
        OR
        (year = 'START_YEAR' AND month = 'END_MONTH' AND day <= 'END_DAY')
        OR
        -- Different years
        (year > 'START_YEAR' AND year < 'END_YEAR')
        OR
        (year = 'END_YEAR' AND month < 'END_MONTH' AND day BETWEEN '01' AND '31')
        OR
        (year = 'END_YEAR' AND month = 'END_MONTH' AND day <= 'END_DAY')
    )
    AND
    t BETWEEN TIMESTAMP 'START_YEAR-START_MONTH-START_DAY 00:00:00' AND TIMESTAMP 'END_YEAR-END_MONTH-END_DAY 00:00:00'

推荐答案

我最终使用了this AWS examplethis blog article中描述的方法.

具体地说,我按照最初列出的方式设置了我的S3 struct ,只是我go 掉了配置单元符号(这可以保留,但我认为在这种情况下,预测日期格式会变得更加混乱):

s3://bucket/device/table_x/2000/01/02/xyz.parquet

为此,我将我的表属性设置为使用分区投影,设置如下:

 "projection.enabled" = "true",
 "projection.date_created.type" = "date",
 "projection.date_created.format" = "yyyy/MM/dd",
 "projection.date_created.range" = "2000/01/01,NOW",
 "projection.date_created.interval" = "1",
 "projection.date_created.interval.unit" = "DAYS",
 "storage.location.template" = "s3://bucket/device/table_x/${date_created}/"

在我的表架构中,我将JSON更新为以下内容:

[
  {
    "Name": "t",
    "Type": "timestamp",
    "Comment": ""
  },
  {
    "Name": "a1",
    "Type": "double",
    "Comment": ""
  },
  {
    "Name": "a2",
    "Type": "double",
    "Comment": ""
  },
  {
    "Name": "date_created",
    "Type": "string",
    "Comment": "",
    "PartitionKey": "Partition (0)"
  }
]

在进行这些更新之后,我现在可以使用Pilcrow提出的更简单的分区 struct 来查询数据:

SELECT
    Count(a1) as AVG_a1                 
FROM
    tbl_11111111_a
WHERE
    date_created BETWEEN '2000/01/01' AND '2000/01/02'

这里的要点是,我能够保留子文件夹嵌套的日期 struct (对于非Athena datalake目的,我更喜欢这种 struct ),但仍然保留用于我的Athena查询的简单SQL查询WHERE语句,同时使用高效的分区投影.

还要注意,我相信Pilcrow在分析我原来的年/月/日SQL查询效率低下时是正确的,因为我发现在切换到与一天5分钟间隔相关的查询的新 struct 时,速度提高了66%.

Sql相关问答推荐

在SQL中向每个子字节组添加字节行

当交叉联接3个或更多表时,实体框架中是否会传输冗余的行数据并占用数据库带宽?

对非RUST源代码字符串使用`stringify!`,例如SQL查询

当一个视图在Postgres中失效时?

如何使用SQL Server中的Nodes()方法执行与OPENXML相同的操作

无法将发票与产品价格相关联

按两列分组,并根据SQL中的条件返回第三个列值

从单个表达式中的分隔字符串中取平均值

其中使用表名作为;行值;记录?

在 Postgres 中将结果按几十年划分

使用 union 的有序结果获取行数

如何使用 Google BigQuery 中的条件根据特定列值连接列的 N 行?

在Snowflake中,如何将以逗号和连字符分隔的多个混合数值拆分成数字列表

try 将多行折叠为单个结果

Clob 问题 - 将 clob 列拆分为多行

如何根据某个值在where子句中添加某个条件

如何对 SQL 表中的连续时间戳进行分组?

如何防止 SQL 中的负收入值并将其重新分配到接下来的月份?

连续几天购买的客户

CURRENT_ROW 窗口框架上的 SQL 滞后