也许这个问题过于笼统,但我认为值得一试。
我正在使用一个包含270个字段的表。它按日期划分(如dt = 20180101)。但是当我们用查询命中这个表时,我们实际上是在进行整个表扫描,因为我们使用where子句中不是dt的字段。我想知道为这个表启用分组的正确方法是什么。我可以选择其中一个where子句字段并为其启用bucketing。例如:
PARTITIONED BY (
dt INT
)
CLUSTERED BY (
class
)
INTO 16 BUCKETS
另一种方法是使用多于1个字段进行分组:
PARTITIONED BY (
dt INT
)
CLUSTERED BY (
class, other_field, other_field_2
)
INTO 128 BUCKETS
多个领域是否值得屈服?我想只有在select中存在相同的确切字段时才会加速查询。
另一个问题,是否值得至少按多个字段排序,所以当读取文件时它是顺序读取的?像这样:
PARTITIONED BY (
dt INT
)
CLUSTERED BY (
class
)
SORTED BY (
other_field, other_field_2
)
INTO 16 BUCKETS
答案 0 :(得分:1)
首先,如果您通常不按日期查询,并且查询跨越多个日期,则可能需要更改分区策略。 不必总是只查询1个或几个日期,但是如果您的查询通常与“日期”过滤完全无关,则应该更改它!
第二,存储基本上是根据存储列的哈希值来拆分数据。因此,它可以帮助您将数据拆分到文件系统中大小相等的文件夹中,并帮助mapReduce程序对其进行高效运行来管理分区。但是,将存储桶放入大量存储桶中也会产生负面影响,因为所有此类元数据也都存储在Hive Metastore中。因此,当您执行某些查询时,首先读取此元数据,然后根据元数据查询的结果,从文件系统中读取实际数据(部分实际数据)。 因此,实际上,没有专门的存储规则。关于应该有多少个存储桶以及应该在哪些所有列上存储存储。
因此,您应该调查自己的查询并制定相应的计划!
第三,排序在查询时确实有帮助,因为引擎很容易降低过滤和排序标准。但是,当您在表上启用排序时,数据的摄取实际上比未启用排序的情况要慢一些!但是绝对可以在高查询系统中为您带来好处。
因此,总而言之,这三种都是优化技术,并不针对其应用程序持有任何特定规则。这完全取决于您的用例!
希望这会有所帮助!!