【问题标题】:What could make these two queries returning different results?是什么让这两个查询返回不同的结果?
【发布时间】:2019-04-11 22:32:48
【问题描述】:

我在 Amazon Athena 上有一个 ELB 日志表,我正在尝试通过 url 请求每日请求。该表的结构是the one described here,但我还添加了日、月和年的分区,用于按日、月等查询日志... 我正在使用这样的查询对表进行分区:

ALTER TABLE elb_logs ADD IF NOT EXISTS PARTITION (year='2019',month='03',day='*') location 's3://my-logs-bucket/my-load-balancer/AWSLogs/526654419886/elasticloadbalancing/eu-west-1/2019/03/'

然后我询问 2019 年 3 月 1 日的日志条目,如下所示:

SELECT count(*)
    FROM elb_logs
    WHERE year='2019'
    AND month='03'
    AND day='01'

得到 590 个结果,那么如果我执行这个查询:

SELECT count(*), DATE(from_iso8601_timestamp(time))
    FROM elb_logs
    WHERE year='2019'
         AND month='03'
         AND day='*'
    GROUP BY DATE(from_iso8601_timestamp(time))

我也得到 590 作为 3 月 1 日的计数,但是如果我执行这个(没有日期条件):

SELECT count(*), DATE(from_iso8601_timestamp(time))
    FROM elb_logs
    WHERE year='2019'
         AND month='03'
    GROUP BY DATE(from_iso8601_timestamp(time))

我得到 1180 作为结果计数,这是不正确的。为什么是这样?指定DAY='*' 和不指定DAY 有什么区别?它们不应该是等价的吗?

【问题讨论】:

  • 您想在PARTITION 语句中使用day='*' 实现什么目标?
  • 我这样对表进行了分区,以便能够在需要时查询任何一天的日志。我实际上找不到我读到的文档,因为我很久以前就做了。
  • 这有效地将day 字段设置为该分区中包含的任何行的*。字段内容是根据分区目录的名称设置的。事实上,我不确定你会从哪里获得 day='01' 的行,除非你使用该特定值创建了一个单独的分区。
  • 好吧,这对我来说有点澄清,day='01' 结果可能来自另一个专门执行其他操作的分区。可以多次设置这些值吗,我的意思是,如果我为 S3 文件夹设置 *,然后使用其他字符设置另一个分区。两者都可以查询,还是第一个被覆盖?
  • 默认的分区方式是目录名定义值,例如s3://my-bucket/table/year=2019/month=03/day=01。在这种情况下,该目录中的所有行都将具有命名字段的这些值。或者,当使用您提供的语法使用ADD PARTITION 时,表示该指定目录中的所有行都具有year='2019',month='03',day='*'

标签: amazon-athena presto


【解决方案1】:

有分区名称和分区位置。

分区:

  • month=03,day=01
  • month=03,day=*

当您对day 列进行无条件查询时,两个分区都匹配。 碰巧的是,它们包含相同的文件(因为它们共享它们的物理位置)。 由于(显然)没有对正在读取的文件进行重复数据删除(分区应该是不重叠的),因此相同的数据文件被读取了两次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多