分区
分区是一种用于增强配置单元中查询性能的技术。通过将数据重组到子目录中来完成此操作。让我们通过一个例子来理解这个概念。
假设我们有一个10 GB的大文件,其中包含客户的地理数据。现在,我们要提取特定国家/地区和特定employeeeId的记录。为此,它将执行表扫描以读取所有行,然后仅选择满足给定谓词的那些记录。
现在,如果我们按国家对表进行分区并运行查询,它将不会扫描整个表,而只会查看该特定国家/地区的子目录。我们可以看到查询的执行计划,以验证它仅查找一个过滤谓词(即employeeId)。它将直接进入子目录/ Country ='India’并在该子目录中搜索员工。此技术称为分区修剪。该查询将过滤掉不需要扫描的分区,因此非常有效。,用于分区的列也不是create语句的一部分,但可以在查询中使用。它们称为虚拟分区列。每当我们将这些虚拟分区列用作过滤器时,查询服务的速度都比未分区表快得多,尤其是在数据量很大的情况下。
分区时要记住的事情:
- 您用于分区的列的基数应该较低,即该列的不同值较低。原因是,由于基数高,我们最终将拥有许多子目录或文件。由于映射器的数量取决于输入大小和块大小,因此创建许多分区最终将使用许多映射器,并且在大多数情况下,这将导致资源浪费。
- 许多分区还会发生的另一件事是,在内存中跟踪文件系统元数据的名称节点也将具有不必要的开销,因为它现在必须跟踪许多分区。
- 当我们在外部表上创建分区时,位置是可选的。但是我们应该始终提供位置(例如root / a / b),因为以后可以将其用于与配置单元metastore同步。因此,如果您提供了位置,然后添加了诸如root / a / b / country ='India’之类的子目录,那么当我们运行命令时,请选择MSCK Repair Table Tablename。它将自动添加该分区。
因此,可以说分区在以下情况下很有用:
我们的分区数量有限
所有分区均分
桶
当由于分区不相等或分区数量太多而无法通过分区提高查询效率时,我们可以尝试进行存储。存储桶概念基于存储桶列上的哈希函数。产生相同哈希值的记录将始终位于同一存储桶中。
要将表划分为存储桶,我们使用Clustered by子句。每个存储桶就像目录中的文件,并且所有文件均等分布。
装桶的优点是:
- 在存储桶的表上进行Map-Side联接的速度更快,因为它们的大小相似。
- 我们可以保持记录在每个存储桶中排序
- 当数据按存储桶中的列排序并用于联接时,Map端联接甚至更快
- 他们还提供对非存储表的有效采样
- 使用存储桶,我们始终可以定义要形成的存储桶数,而在分区中则并非如此
- 可以在有分区或无分区的情况下使用存储桶
如何创建存储桶表:
Create Table t1(a INT,b STRING,c STRING)
CLUSTERED BY (b) BUCKETS 128 BUCKETS
Hive不会对加载到表中的数据强制执行存储。创建表后,我们必须对其进行管理。有两种方法可以实现:
Set mapred.reduce.tasks=64(number of buckets)
Insert Overwrite Table t1
Select a,b,c from table2 cluster by b
Set hive.enforce.bucketing=true;
Insert Overwrite Table t1