【问题标题】:Partitioning or bucketing hive table based on only month/year to optimize queries仅基于月/年对 Hive 表进行分区或分桶以优化查询
【发布时间】:2015-01-06 22:36:18
【问题描述】:

我正在构建一个包含大约 40 万行消息应用程序数据的表。 当前表的列如下所示:


message_id (int)| sender_userid (int)| other_col (字符串)| other_col2 (int)| create_dt(时间戳)

我将来要运行的许多查询将依赖于涉及 create_dt 列的 where 子句。因为我希望这张表会增长,所以我现在想尝试优化它。我知道分区是一种方式,但是当我根据 create_dt 对其进行分区时,结果分区太多,因为我的每个日期都追溯到 2013 年 11 月。

有没有办法改为按日期范围进行分区?每3个月分区一次怎么样?甚至每个月?如果这是可能的 - 我将来是否可能有太多分区使其效率低下?还有哪些其他可能的分区方法?

我还阅读了有关分桶的信息,但据我所知,这仅在您对存储桶所基于的列进行连接时才有用。我很可能只对列 sender_userid (int) 进行联接。

谢谢!

【问题讨论】:

    标签: hadoop hive


    【解决方案1】:

    我认为这可能是过早优化的情况。我不确定您对“太多分区”的定义是什么,但我们有一个类似的用例。我们的表按日期和客户列分区。我们的数据可以追溯到 2013 年 3 月。这创建了大约 160k+ 个分区。我们还使用了日期过滤器,我们没有发现此架构有任何性能问题。

    另一方面,Hive 在扩展到上百个分区和表方面做得越来越好。

    另一方面,我很好奇您为什么首先使用 Hive。 400k 行数据量很小,并不适合 Hive。

    【讨论】:

    • 我同意 hive 对于 400k 行来说是多余的,但 400k 来自少于 5k 的用户,我们预计这两个数字都将呈指数增长。无论如何,这不是重点,因为我只是在问它是如何完成的。另外关于分区大小,我注意到来自以下来源的警告和建议:link“不要过度分区数据。如果小分区太多,递归扫描目录的任务比全表扫描更昂贵的桌子。”
    • @tchoedak 这绝对是一个很好的建议。但是,我不认为您的分区方案是“过度分区”。白天分区很常见。您当然可以按月或按季度进行分区(请参阅@miljanm 的回答)。但是,这会给用户带来不必要的负担,因为您需要同时指定“月份”和“日期”才能使其应用正确的分区过滤器。
    【解决方案2】:

    查看内置 UDF 的 hive。通过它们的正确组合,您可以实现您想要的。这是每个月进行分区的示例(生成可用作分区列值的“YEAR-MONTH”字符串):

    select concat(cast(year(to_date(create_dt)) as string),'-',cast(month(to_date(create_dt)) as string))
    

    但是在日期上进行分区时,拥有多个级别的日期维度通常很有用,因此在这种情况下,您应该有两个分区列,第一个用于年份,第二个用于月份:

    select year(to_date(create_dt)),month(to_date(create_dt))
    

    请记住,时间戳和日期都是字符串,并且像 month() 或 year() 这样的函数会返回整数作为日期字段的值。您可以使用简单的数学运算来找出正确的分区。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      相关资源
      最近更新 更多