如何在 hive 表中选择分区和存储的列?

inf*_*ior 1 hadoop hive partitioning hiveql

以下架构的分区和分桶的理想列是什么?是否有必要两者都实施,还是一个就可以?

user_id INTEGER UNSIGNED,
product_id VARCHAR(20),
gender ENUM('M','F') default NULL,
age VARCHAR(6),
occupation TINYINT UNSIGNED default NULL,
city_category ENUM('A','B','C','D','E') default NULL,
stay_in_current_city_years VARCHAR(6),
martial_status TINYINT UNSIGNED default 0,
product_category_1 TINYINT UNSIGNED default 0,
product_category_2 TINYINT  UNSIGNED default 0,
product_category_3 TINYINT UNSIGNED default 0,
purchase_amount INTEGER UNSIGNED default 0 
Run Code Online (Sandbox Code Playgroud)

主要目标是利用Hive根据以上属性做一些分析。

Gau*_*hah 7

在 hive 中,您根据使用模式创建一个表,因此您应该根据分析查询的外观选择对存储桶进行分区。

但是,建议采取以下措施

分区

  • 分区可帮助您加快谓词(即Where 条件)的查询速度。因此,在您的情况下,ifcity_category是您在 where 条件中大部分时间将使用的字段,您应该选择该字段进行分区。
  • 它可能会降低其他查询的性能。
  • 需要确保基数不要太高,否则,查询性能会下降。

要理解上述几点,您需要了解分区的工作原理。当您创建分区(或子分区)时,Hive 会创建一个具有该名称的子文件夹,并将数据(文件)存储到这些文件夹中。

因此,如果您根据city_category文件进行分区,就会像这样。

/data/table_name/city_category=A
/data/table_name/city_category=B
...
/data/table_name/city_category=E
Run Code Online (Sandbox Code Playgroud)

city_category如果您提供,这有助于 hive 查找特定记录,Where condition因为它只需扫描一个文件夹。

但是,如果您尝试基于 Hive 查找记录user_idproduct_id则需要扫描所有文件夹。

假设您最终基于 进行分区purchase_amount,那么您将拥有很多文件夹。NameNode 必须维护每个文件夹和文件的位置,因此它将在 NameNode 上产生大量负载,并明显降低查询的性能。

分桶

  • 如果您要连接的另一个表具有类似的存储桶,它可以帮助您加快连接查询速度。
  • 然而,最好确保数据在分桶中均匀分布。

分桶的作用是什么,它对给定字段应用哈希,并基于此将给定记录存储在分桶中。

假设您基于city_category并告诉创建 50 个存储桶。

CLUSTERED BY (city_category) INTO 50 BUCKETS
Run Code Online (Sandbox Code Playgroud)

由于我们只有 5 个类别,其他 45 个存储桶将为空,这是您不希望出现的情况,因为它会降低查询的性能。