Hadoop-Impala十大最佳化系列之(1)—分割槽表最佳化-8個方法讓分割槽最最佳化

ultradb發表於2016-12-05

1.1  Hadoop-Impala十大最佳化系列之(1)—分割槽表最佳化-8個方法讓分割槽最最佳化

impala表分割槽

       預設情況下,表中的所有資料檔案都位於一個目錄中。分割槽是在載入過程中基於從一個或多個列的值的物理上劃分資料的技術,以加快對這些列進行測試的查詢。例如,一個school_records表分割槽在年柱,各有不同的年值一個單獨的資料目錄,所有這一年的資料是儲存在目錄中的資料檔案。一個查詢,其中包括一個條件,如 WHERE condition such as YEAR=1966, YEAR IN(1989,1999), or YEAR BETWEEN 1984 AND 1989 ,可以檢查只有從適當的目錄或目錄的資料檔案,大大減少了資料讀取和測試。

以下幾個方面介紹分割槽使用和管理維護:

1)       什麼時候使用分割槽表

2)       對於分割槽表的SQL語句

3)       靜態和動態分割槽子句

4)       分割槽的子目錄的許可權

5)       查詢的分割槽修剪

6)       分割槽鍵列

7)       設定分割槽的不同的檔案格式

8)       管理分割槽

請參見附加外部分割槽表的HDFS目錄結構為例,說明建立分割槽表的語法,基礎目錄結構在HDFS,和如何把分割槽表資料檔案儲存的 Impala外其他地方在HDFS。

Parquet 是 Impala表分割槽的流行格式是因為它很適合處理海量的資料。看到Impala  表分割槽Parquet 表效能考慮查詢效能。

1.1.1  什麼時候使用分割槽表

      分割槽通常是適合以下情況:

       表是非常大的,在讀取整個資料集需要一個不切實際的時間量。

       總是或幾乎總是在分割槽列上的條件查詢的表。在我們的一個表分割槽的例子,SELECT COUNT(*) FROM school_records WHERE year= 1985是有效的,只有對資料的一小部分;但SELECT COUNT(*) FROM school_records具有處理每年一個單獨的資料檔案,從而更全面的工作比在非分割槽表。如果您經常查詢基於姓氏的表,學生證,等等,而不需要測試一年,你可能不會有這樣的劃分方式。

       有合理的基數列(不同值的數量)。如果一個列只有一個小的值,例如男性或女性,你沒有得到太多的效率,透過消除只有約50%的資料讀取每個查詢。如果一列只有幾行的匹配值,處理目錄的數量可以成為一個限制因素,並在每個目錄中的資料檔案可能太小,利用Hadoop的機制在多兆位元組的資料分塊傳輸。例如,您可能會在一年內分割槽統計資料,透過年和月的儲存銷售資料,以及年、月和日的Web流量資料。(一些高容量的輸入資料的使用者甚至可能劃分到每小時和每分鐘。)

 資料已透過提取、變換、和載入(ETL)管道。分割槽列的值從原始資料檔案中剝離,並由目錄名錶示,因此將資料載入到分割槽表中涉及到某種形式的轉換或預處理。

1.1.2  對於分割槽表的SQL語句

      在Impala的SQL語法,分割槽影響這些語句:

      createtable :您在建立表時指定了一個PARTITIONEDBY條件,以確定分割槽列的名稱和資料型別。這些列不包含在表的列中的主要列表中。

       在CDH 5.7 /Impala2.5及更高,你也可以使用分割槽在建立表的條款為SELECT語句。此語法允許您使用一個語句來建立一個分割槽表,將資料複製到它,並基於插入的資料中的值建立新的分割槽。

       改變表:可以新增或刪除分割槽,可以使用一個龐大的資料集的不同部分工作。你可以為一個特定的分割槽指定的HDFS目錄儲存資料檔案。透過日期值劃分的資料,您可能會“老化”不再相關的資料。

       注:如果您正在建立一個分割槽,並指定它的位置,為最大效率,使用一個單一的更改表語句,包括新增分割槽和位置子句,而不是單獨的語句與新增分割槽和設定位置子句。

1.1.3  靜態和動態分割槽子句

      在SQL語句中指定的所有分割槽列稱為靜態分配,因為語句影響單個預測分割槽。例如,您使用靜態分割槽與一個改變表語句,隻影響一個分割槽,或與一個插入語句插入到同一個分割槽中的所有值:

insertinto t1 partition(x=10,y='a') select c1 from some_other_table;

      當你指定分割槽鍵列在INSERT語句,但離開了價值,Impala決定插入哪個分割槽。這種技術被稱為動態分割槽:

insert intot1 partition(x,y='b') select c1, c2 from some_other_table;

-- Createnew partition if necessary based on variable year, month, and day; insert asingle value.

insert intoweather partition(year, month, day) select'cloudy',2014,4,21;

-- Createnew partition if necessary for specified year and month but variable day;insert a single value.

insert intoweather partition(year=2014, month=04, day) select'sunny',22;

      在分割槽子句中指定的更重要的列,在“選擇列表”中需要的列數較少。在選擇列表中的尾隨列以順序替換沒有指定值的分割槽鍵列。

 

1.1.4  分割槽的子目錄的許可權

      預設情況下,如果插入語句建立任何新的子目錄下面的分割槽表,這些子目錄分配許可權的使用者預設的HDFS的許可權。使每個子目錄具有相同的許可權為在HDFS的父目錄,指定--insert_inherit_permissions啟動選項的impalad守護。

1.1.5  查詢的分割槽精簡

      分割槽精簡指的是一個查詢可以跳過一個或多個分割槽對應的資料檔案的機制。如果您可以安排查詢,從查詢執行計劃中刪除大量的不必要的分割槽,查詢使用更少的資源,因此比例更快,更可擴充套件性。

       例如,如果一個表是由列年,月,日,分割槽,然後在條款如年為2013年,其中<2010,或1995和1998讓Impala跳過資料檔案在指定範圍外的所有分割槽之間。同樣地,在一年的2013和1和3之間的一個月,可以精簡更多的分割槽,讀取資料檔案只有一年的一部分。

      要檢查分割槽修剪對於查詢的有效性,在執行它之前檢查解釋輸出為查詢的結果。例如,這個示例顯示了一個有3個分割槽的表,其中查詢只讀取其中的1個分割槽。符號#partitions=1/3在解釋計劃證實了impala可以做適當的分割槽修剪。

[localhost:21000]> insert into census partition (year=2010) values ('Smith'),('Jones');

[localhost:21000]> insert into census partition (year=2011) values('Smith'),('Jones'),('Doe');

[localhost:21000]> insert into census partition (year=2012) values ('Smith'),('Doe');

[localhost:21000]> select name from census where year=2010;

+-------+

| name  |

+-------+

| Smith |

| Jones |

+-------+

[localhost:21000]> explain select name from census where year=2010;

+------------------------------------------------------------------+

| ExplainString                                                   |

+------------------------------------------------------------------+

| PLANFRAGMENT 0                                                 |

|   PARTITION: UNPARTITIONED                                       |

|                                                                  |

|   1:EXCHANGE                                                    |

|                                                                 |

| PLANFRAGMENT 1                                                  |

|   PARTITION: RANDOM                                              |

|                                                                 |

|   STREAM DATA SINK                                              |

|     EXCHANGE ID: 1                                               |

|     UNPARTITIONED                                               |

|                                                                 |

|   0:SCAN HDFS                                                   |

|      table=predicate_propagation.census #partitions=1/3 size=12B |

+------------------------------------------------------------------+

      對於在查詢的每個階段實際讀取和處理的資料量的報表,在執行查詢後立即檢查彙總命令的輸出。對於一個更詳細的分析,看配置檔案命令的輸出;它包括在配置檔案輸出的開始附近的這個相同的彙總報告。

1)       檢查是否對查詢進行分割槽修剪

2)       什麼SQL構造分割槽修剪工作

3)       動態分割槽修剪

1.1.5.1 檢查是否對查詢進行分割槽修剪

      要檢查分割槽修剪對於查詢的有效性,在執行它之前檢查解釋輸出為查詢的結果。例如,這個示例顯示了一個有3個分割槽的表,其中查詢只讀取其中的1個分割槽。符號#分割槽= 1 / 3在解釋計劃證實了impala可以做適當的分割槽修剪。

[localhost:21000]> insert into census partition (year=2010) values ('Smith'),('Jones');

[localhost:21000]> insert into census partition (year=2011) values('Smith'),('Jones'),('Doe');

[localhost:21000]> insert into census partition (year=2012) values ('Smith'),('Doe');

[localhost:21000]> select name from census where year=2010;

+-------+

| name  |

+-------+

| Smith |

| Jones |

+-------+

[localhost:21000]> explain select name from census where year=2010;

+------------------------------------------------------------------+

| ExplainString                                                  |

+------------------------------------------------------------------+

| PLANFRAGMENT 0                                                 |

|   PARTITION: UNPARTITIONED                                       |

|                                                                 |

|   1:EXCHANGE                                                    |

|                                                                 |

| PLANFRAGMENT 1                                                 |

|   PARTITION: RANDOM                                              |

|                                                                 |

|   STREAM DATA SINK                                              |

|     EXCHANGE ID: 1                                              |

|     UNPARTITIONED                                               |

|                                                                 |

|   0:SCAN HDFS                                                   |

|      table=predicate_propagation.census #partitions=1/3 size=12B |

+------------------------------------------------------------------+

      對於在查詢的每個階段實際讀取和處理的資料量的報表,在執行查詢後立即檢查彙總命令的輸出。對於一個更詳細的分析,看配置檔案命令的輸出;它包括在配置檔案輸出的開始附近的這個相同的彙總報告。

1.1.5.2 什麼SQL構造分割槽修剪工作

      impala甚至可以做分割槽修剪的情況下,分割槽鍵列是不能直接比較恆定,透過傳遞性質的WHERE子句中的其他部分。這種技術被稱為謂詞的傳播,並在impala1.2.2後來。在這個示例中,普查表包括另一列,該列指示當資料被收集時,發生在10年的時間間隔內。即使查詢並不比分割槽鍵列(年)到一個恆定值,impala可以推斷出,只有= 2010是必需的分割槽的一年,又一次只讀取了3個分割槽1。

[localhost:21000]> drop table census;

[localhost:21000]> create table census (name string, census_year int) partitioned by (yearint);

[localhost:21000]> insert into census partition (year=2010) values('Smith',2010),('Jones',2010);

[localhost:21000]> insert into census partition (year=2011) values('Smith',2020),('Jones',2020),('Doe',2020);

[localhost:21000]> insert into census partition (year=2012) values('Smith',2020),('Doe',2020);

[localhost:21000]> select name from census where year = census_year and census_year=2010;

+-------+

|name  |

+-------+

| Smith |

| Jones |

+-------+

[localhost:21000]> explain select name from census where year = census_year andcensus_year=2010;

+------------------------------------------------------------------+

| ExplainString                                                  |

+------------------------------------------------------------------+

| PLANFRAGMENT 0                                                 |

|   PARTITION: UNPARTITIONED                                       |

|                                                                 |

|   1:EXCHANGE                                                     |

|                                                                 |

| PLANFRAGMENT 1                                                 |

|   PARTITION: RANDOM                                              |

|                                                                  |

|   STREAM DATA SINK                                              |

|     EXCHANGE ID: 1                                              |

|     UNPARTITIONED                                               |

|                                                                  |

|   0:SCAN HDFS                                                   |

|      table=predicate_propagation.census #partitions=1/3 size=22B |

|      predicates: census_year = 2010, year =census_year          |

+------------------------------------------------------------------+

      如果一個檢視適用於一個分割槽表,任何分割槽修剪都認為在原始查詢和任何額外的謂詞在查詢中的語句,是指檢視的子句。impala1.4之前,只有在條款對原始查詢從建立檢視的語句進行分割槽修剪。

      在解析函式和分割槽表的查詢中,只發生在由解析函式呼叫的分割槽中命名的列的分割槽修剪。例如,如果一個解析函式查詢有一個條款,如在年= 2016,使查詢修剪所有其他年分割槽的方法是包括在解析函式呼叫劃分;例如,在(分割槽的一年,other_columns other_analytic_clauses)。

1.1.5.3 動態分割槽修剪

      原來的機制用於修剪分割槽是靜態分割槽修剪,在其中的條件,在條款進行分析,以確定提前哪些分割槽可以安全地跳過。在Impala 2.5 /CDH5.7及更高版本,impala可以執行動態分割槽修剪,在分割槽資訊中查詢收集,和impala修剪不必要的分割槽方式是提前預測不切實際。

例如,如果分割槽鍵列進行比較的文字值WHERE子句中,impala可以執行靜態分割槽修剪規劃階段在閱讀相關的分割槽:

-- Thequery only needs to read 3 partitions whose key values are known ahead of time.

-- That'sstatic partition pruning.

SELECTCOUNT(*) FROM sales_table WHERE year IN (2005, 2010, 2015);

      動態分割槽修剪涉及使用資訊只有在執行時,如查詢結果:

createtable yy (s string) partitioned by (year int) stored as parquet;

insert intoyy partition (year) values ('1999', 1999), ('2000', 2000),

  ('2001', 2001), ('2010',2010);

computestats yy;

 

createtable yy2 (s string) partitioned by (year int) stored as parquet;

insert intoyy2 partition (year) values ('1999', 1999), ('2000', 2000),

  ('2001', 2001);

computestats yy2;

 

-- Thequery reads an unknown number of partitions, whose key values are only

-- known atrun time. The 'runtime filters' lines show how the information about

-- thepartitions is calculated in query fragment 02, and then used in query

-- fragment00 to decide which partitions to skip.

explainselect s from yy2 where year in (select year from yy where year between 2000and 2005);

+----------------------------------------------------------+

| ExplainString                                          |

+----------------------------------------------------------+

| EstimatedPer-Host Requirements: Memory=16.00MB VCores=2 |

|                                                          |

|04:EXCHANGE [UNPARTITIONED]                              |

| |                                                       |

| 02:HASHJOIN [LEFT SEMI JOIN, BROADCAST]                |

| |  hash predicates: year = year                          |

| |  runtime filters: RF000 <- year                       |

| |                                                       |

||--03:EXCHANGE [BROADCAST]                               |

| |  |                                                    |

| |  01:SCAN HDFS [dpp.yy]                                 |

| |     partitions=2/4 files=2 size=468B                   |

| |                                                       |

| 00:SCANHDFS [dpp.yy2]                                  |

|    partitions=2/3 files=2 size=468B                      |

|    runtime filters: RF000 -> year                       |

+----------------------------------------------------------+

      在這種情況下,impala評價子查詢,子查詢結果傳送所有Impala節點參與查詢,然後每個impalad守護程式採用動態分割槽剪枝最佳化與相關鍵值只讀分割槽。

動態分割槽修剪是特別有效的查詢,涉及幾個大的分割槽表的聯接。評估聯接謂詞的子句,通常需要從某些表的所有分割槽中讀取資料。如果該查詢的WHERE子句中引用的分割槽鍵列,impala現在經常可以跳過閱讀許多的分割槽在評估條款。動態分割槽修剪最佳化減少了在查詢過程中的網路儲存和傳輸的I / O和中間資料量的量。

      當溢位到磁碟功能是一個連線節點在查詢啟用,impala不產生任何執行過濾器,主機上的連線操作。查詢中的其他連線節點不受影響。

      動態分割槽修剪是執行時過濾功能的一部分,它適用於其他型別的查詢,除了對分割槽表的查詢。看到執行的impala查詢有關此功能的詳細的過濾。

 

1.1.6  分割槽鍵列

      您選擇的列作為分割槽鍵應該是經常用於篩選查詢結果的重要的大型查詢。流行的例子是一些組合的一年,一個月,和一天的資料有相關的時間值,和地理區域的資料時,與一些地方。

      基於時間的資料,分離出獨立的部分納入自己的欄目,因為impala不能劃分一個時間戳列。

      該分割槽列的資料型別不具有對儲存要求的效果顯著,因為從這些列的值不儲存在資料檔案中,而他們是在HDFS目錄名稱的字串。

      在CDH 5.7 /impala2.5及更高版本,可以使optimize_partition_key_scans查詢選項來加快查詢的速度,僅指分割槽鍵列,如選擇最大(年)。預設情況下,此設定沒有啟用,因為如果表中包含沒有實際資料的分割槽目錄,則查詢的行為將略有不同。看到optimize_partition_key_scans查詢詳情。

      分割槽表可以包含複雜的型別列。所有分割槽鍵列必須為標量型別。

      記住,當impala查詢儲存在HDFS的資料,它是最有效的使用多位元組的檔案利用HDFS塊大小。實木複合地板表,塊的大小(和資料檔案大小是理想)2 256 MB,後來impala。因此,避免指定太多的分割槽鍵列,這可能會導致單個分割槽只包含少量的資料。例如,如果你每天收到1個資料,你可能會被一年一個月,一天一天;而如果你每分鐘收到5個資料,你可能會被一年、一個月、一天、一小時、一分鐘劃分。如果你與一個地理成分的資料,你可能會劃分郵政編碼,如果您有許多兆位元組的每個郵政編碼資料,但如果沒有的話,你可能會被一些大的區域,如城市、州或國家劃分。狀態

      如果你經常執行彙總等功能min(),max(),計數(不同的)分割槽鍵列,考慮啟用optimize_partition_key_scans查詢最佳化查詢。這一特徵在CDH 5.7 /impala2.5及更高版本可用。看到optimize_partition_key_scans查詢選項,這個選項適用於查詢的種類,和輕微的差異如何分割槽進行評估時,該查詢選項啟用。

1.1.7  設定分割槽的不同的檔案格式

      分割槽表有靈活性,使用不同的分割槽使用不同的檔案格式。(關於不同的檔案格式支援背景資訊看,impala、impala和Hadoop檔案格式。)例如,如果你在文字格式最初收到資料,然後接收新的資料格式,並最終開始RCFile,拼花格式接收資料,這些資料可以駐留在同一個表的查詢。您只需要確保表的結構,以便使用不同的檔案格式的資料檔案駐留在單獨的分割槽中。

      例如,這裡是你如何可以從文字到地板的資料你不同年接收資料:

[localhost:21000]> create table census (name string) partitioned by (year smallint);

[localhost:21000]> alter table census add partition (year=2012); -- Text format;

 

[localhost:21000]> alter table census add partition (year=2013); -- Text format switches toParquet before data loaded;

[localhost:21000]> alter table census partition (year=2013) set fileformat parquet;

 

[localhost:21000]> insert into census partition (year=2012) values ('Smith'),('Jones'),('Lee'),('Singh');

[localhost:21000]> insert into census partition (year=2013) values('Flores'),('Bogomolov'),('Cooper'),('Appiah');

      在這一點上,HDFS目錄 year=2012包含一個文字格式的資料檔案,而HDFS目錄 year=2013包含一個複合資料檔案。和總是一樣,當載入不平凡的資料時,您將使用插入…選擇或載入資料以大批次匯入資料,而不是插入…值,產生小的檔案,是低效的現實世界的查詢。

       對於其他型別的檔案,impala不能創造本身,你可以切換到蜂巢的問題修改表…設定檔案格式報表和報表資料插入或負載有。切換回Impala後,發出宣告,重新整理table_nameImpala承認任何分割槽或新新增的資料透過hive。

1.1.8  管理分割槽

      你可以新增,刪除,設定預期的檔案格式,或一組資料檔案HDFS位置個別分割槽impala表內。有關語法細節的更改表語句,並在包含分割槽的分割槽的管理表上設定不同的檔案格式的不同的檔案格式。

      注:如果您正在建立一個分割槽,並指定它的位置,為最大效率,使用一個單一的更改表語句,包括新增分割槽和位置子句,而不是單獨的語句與新增分割槽和設定位置子句。

      當一個分割槽被刪除時,資料檔案會發生什麼,取決於分割槽表是否被指定為內部或外部的。對於內部(託管)表,資料檔案已被刪除。例如,如果分割槽表中的資料是儲存在其他地方的原始資料檔案的副本,則可以透過刪除不再需要的舊分割槽來儲存磁碟空間,知道原始資料在需要時仍然可用。對於一個外部表,資料檔案將被單獨留下。例如,刪除一個分割槽沒有刪除相關的檔案讓impala考慮更小的分割槽,提高查詢效率和減少表的DDL操作的開銷;如果資料再次需要後,你可以再新增分割槽。看到的細節和例子的impala表概述。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24179204/viewspace-2129707/,如需轉載,請註明出處,否則將追究法律責任。

相關文章