Impala 分区表-1


默认情况下,表的所有数据文件都位于一个目录中。分区是一种在加载期间根据一个或多个列的值对数据进行物理划分的技术,以加速测试这些列的查询。例如,对于按school_records列分区的表year,每个不同的年份值都有一个单独的数据目录,该年份的所有数据都存储在该目录中的数据文件中。其包括一个查询WHERE条件,例如YEAR=1966YEARIN(1989,1999),或YEARBETWEEN1984AND1989只能从相应的目录或目录检查数据文件,大大减少了数据的读取和测试的量。

Parquet是用于分区Impala表的流行格式,因为它非常适合处理大量数据。

何时使用分区表

分区通常适用于:

  • 非常大的表,读取整个数据集需要花费不切实际的时间。
  • 总是或几乎总是使用分区列上的条件查询的表。在我们的按年份分区的表示例中,SELECTCOUNT(*)FROMschool_recordsWHEREyear=1985效率很高,只检查了一小部分数据;但SELECTCOUNT(*)FROMschool_records每年必须处理一个单独的数据文件,导致比未分区表更多的整体工作。如果您经常根据姓氏、学生ID等查询表而不测试年份,您可能不会以这种方式分区。
  • 具有合理基数的列(不同值的数量)。如果一列只有少量值,例如MaleFemale,您不会因为每个查询只消除大约50%的要读取的数据而提高效率。如果一列只有几行与每个值匹配,则要处理的目录数量可能成为限制因素,并且每个目录中的数据文件可能太小而无法利用Hadoop机制以多兆字节块传输数据.例如,您可以按年对人口普查数据进行分区,按年和月存储销售数据,并按年、月和日对Web流量数据进行分区。(一些具有大量传入数据的用户甚至可能会分区到单独的小时和分钟。)
  • 已经通过提取、转换和加载(ETL)管道的数据。分区列的值从原始数据文件中剥离出来并由目录名称表示,因此将数据加载到分区表中涉及某种转换或预处理。

分区表的SQL语句

就ImpalaSQL语法而言,分区会影响这些语句:

  • CREATETABLE:您PARTITIONEDBY在创建表时指定一个子句来标识分区列的名称和数据类型。这些列不包括在表的主列列表中。
  • 在Impala2.5及更高版本中,您还可以在PARTITIONEDBY语句中使用子句CREATETABLEASSELECT。此语法允许您使用单个语句创建分区表,将数据复制到其中,并根据插入数据中的值创建新分区。

ALTERTABLE:您可以添加或删除分区,以处理庞大数据集的不同部分。您可以指定保存特定分区的数据文件的HDFS目录。对于按日期值分区的数据,您可能会“老化”不再相关的数据。

  • 注意:如果您是第一次创建分区并指定其位置,为了获得最大效率,请使用ALTERTABLE包含ADDPARTITIONandLOCATION子句的单个语句,而不是包含ADDPARTITIONandSETLOCATION子句的单独语句。
  • INSERT:当您将数据插入分区表时,您标识了分区列。来自每一插入行的一个或多个值不存储在数据文件中,而是确定存储该行值的目录。您还可以使用INSERTOVERWRITE语句指定将一组数据加载到哪个分区;您可以替换特定分区的内容,但不能将数据附加到特定分区。默认情况下,如果INSERT语句在分区表下创建任何新子目录,则这些子目录会被分配给impala用户的默认HDFS权限。要使每个子目录具有与其在HDFS中的父目录相同的权限,请‑‑insert_inherit_permissions为impalad守护程序指定启动选项。
  • 尽管SELECT无论表是否分区,语句的语法都是相同的,但查询与分区表的交互方式会对性能和可伸缩性产生巨大影响。允许查询在查询期间跳过某些分区的机制称为分区修剪;有关详细信息,请参阅查询的分区修剪
  • 在Impala1.4及更高版本中,有一条SHOWPARTITIONS语句显示有关表中每个分区的信息。有关详细信息,请参阅SHOW声明

静态和动态分区子句

在SQL语句中指定所有分区列称为静态分区,因为该语句影响单个可预测分区。例如,您将静态分区用于ALTERTABLE仅影响一个分区的INSERT语句,或将所有值插入同一分区的语句:

insertintot1partition(x=10,y='a')selectc1fromsome_other_table;

当您在INSERT语句中指定一些分区键列,但忽略这些值时,Impala会确定要插入的分区。这种技术称为动态分区:

insertintot1partition(x,y='b')selectc1,c2fromsome_other_table;
--Createnewpartitionifnecessarybasedonvariableyear,month,andday;insertasinglevalue.
insertintoweatherpartition(year,month,day)select'cloudy',2014,4,21;
--Createnewpartitionifnecessaryforspecifiedyearandmonthbutvariableday;insertasinglevalue.
insertintoweatherpartition(year=2014,month=04,day)select'sunny',22;

您在PARTITION子句中指定的键列越多,SELECT列表中所需的列就越少。SELECT列表中的尾随列被替换为没有指定值的分区键列。

刷新单个分区

REFRESH当新数据文件通过某些非Impala机制(例如Hive或Spark作业)加载到分区时,该语句通常与分区表一起使用。该REFRESH语句使Impala知道新的数据文件,以便它们可以在Impala查询中使用。由于分区表通常包含大量数据,因此REFRESH对完整分区表的操作可能需要大量时间。

在Impala2.7及更高版本中,您可以在语句中包含一个子句,以便仅刷新单个分区。例如,。分区规范必须包括所有分区键列。有关语法和用法的更多详细信息和示例,请参阅REFRESH语句PARTITION(partition_spec)REFRESHREFRESHbig_tablePARTITION(year=2017,month=9,day=30)REFRESH

分区子目录的权限

默认情况下,如果INSERT语句在分区表下创建任何新子目录,则这些子目录会被分配给impala用户的默认HDFS权限。要使每个子目录具有与其在HDFS中的父目录相同的权限,请‑‑insert_inherit_permissions为impalad守护程序指定启动选项。

查询的分区修剪

分区修剪是指查询可以跳过读取一个或多个分区对应的数据文件的机制。如果您可以安排查询从查询​​执行计划中删除大量不必要的分区,则查询使用的资源更少,因此按比例更快且更具可扩展性。

例如,如果一个表是由列分配YEARMONTH以及DAY,然后WHERE条款如WHEREyear=2013WHEREyear<2010,或WHEREyearBETWEEN1995AND1998允许帕拉跳过该特定范围之外的所有分区中的数据文件。同样,WHEREyear=2013ANDmonthBETWEEN1AND3可以修剪更多分区,仅读取一年中的一部分数据文件。

检查查询是否发生分区修剪

要检查查询分区修剪的有效性,请EXPLAIN在运行查询之前检查查询的输出。例如,此示例显示一个具有3个分区的表,其中查询仅读取其中的1个。该符号#partitions=1/3EXPLAIN计划证实,黑斑羚可以做适当的分区修剪。

[localhost:21000]>insertintocensuspartition(year=2010)values('Smith'),('Jones');
[localhost:21000]>insertintocensuspartition(year=2011)values('Smith'),('Jones'),('Doe');
[localhost:21000]>insertintocensuspartition(year=2012)values('Smith'),('Doe');
[localhost:21000]>selectnamefromcensuswhereyear=2010;
+-------+
|name|
+-------+
|Smith|
|Jones|
+-------+
[localhost:21000]>explainselectnamefromcensuswhereyear=2010;
+------------------------------------------------------------------+
|ExplainString|
+------------------------------------------------------------------+
|PLANFRAGMENT0|
|PARTITION:UNPARTITIONED|
||
|1:EXCHANGE|
||
|PLANFRAGMENT1|
|PARTITION:RANDOM|
||
|STREAMDATASINK|
|EXCHANGEID:1|
|UNPARTITIONED|
||
|0:SCANHDFS|
|table=predicate_propagation.census#partitions=1/3size=12B|
+------------------------------------------------------------------+

对于在查询的每个阶段实际读取和处理的数据量的报告,请SUMMARY在运行查询后立即检查命令的输出。更详细的分析,查看PROFILE命令的输出;它在配置文件输出的开头附近包含相同的摘要报告。