Hadoop-impala十大最佳化之(2)—impala連線查詢效能最佳化及最佳實踐

ultradb發表於2016-12-06

1.1  Hadoop-impala十大最佳化之(2)—impala連線查詢的效能最佳化

        涉及連線操作的查詢通常需要更多的調整,而不是僅指一個表的查詢。從聯接查詢集合查詢的結果集的最大大小是所有聯接表中的行數的乘積。當加入數個表有數以百萬計或數十億的行,任何錯過的機會過濾結果集,或其他低效的查詢,可能導致一個操作,不完成在一個實際的時間,必須被取消。

         調整Impala的最簡單的方法連線查詢是收集統計每個表參與聯接的計算統計表,然後讓Impala自動最佳化基於每個表的大小的查詢,對每一列的不同值的數量,等等。計算統計表和連線最佳化了Impala1.2.2新特點。對於每個表的精確統計,在將資料載入到該表中後,發出計算統計報表,如果資料量大幅度的改變,載入資料,新增一個分割槽,等等。

        如果沒有可用的統計資訊在連線查詢所有表,或者如果Impala選擇連線順序,是不是最有效的,你可以重寫自動連線順序最佳化透過指定straight_join關鍵詞後立即選擇關鍵詞。在這種情況下,Impala用出現的查詢指導順序處理。

         當你使用straight_join技術,你必須手動而不是依靠Impala最佳化器查詢表的連線。該最佳化使用複雜的技術來估計連線的每個階段的結果集的大小。對於手動排序,採用這種啟發式的方法開始,然後實驗來微調順序:

指定最大的表。這個表是由每個Impala節點從磁碟讀取,其規模不是很大的記憶體使用情況的查詢。

         下一步,指定最小的表。第二、第三、等表的內容都在網路上傳輸。要將連線查詢的每個後續階段的結果集的大小減到最小。最有可能的方法是先加入一個小的表,這樣結果集仍然很小,即使隨後的較大的表被處理。

         加入下一個最小的表,然後是下一個最小的,等等。

         例如,如果你有表大,中,小,微小,邏輯連線順序嘗試將是大,微小,小,中。

        術語“最大”和“最小”是指基於每個表中的行和列的數量的中間結果集的大小,是結果集的一部分。例如,如果你加入一個表的銷售與另一個表的客戶,查詢可能會發現從100個不同的客戶,共有5000採購的結果。在這種情況下,您將指定選擇…從銷售連線客戶……,把客戶放在右邊,因為它在這個查詢的上下文中是小的。

        impala的查詢計劃選擇不同的技術之間進行連線查詢,根據表的絕對和相對大小。廣播連線是預設的,在右邊的表被認為是小於左邊的表,它的內容被髮送到查詢中涉及的所有其他節點上。另一種技術被稱為一個分割槽的連線(不涉及到一個分割槽表),這是更適合於大表的大小大致相等。使用這種技術,每個表的一部分被髮送到適當的其他節點,其中的行的子集可以被並行處理。廣播或分割槽連線的選擇也取決於在聯接中的所有表可用的統計資料,由計算統計報表所收集的資料中的所有表。

        要檢視哪些連線策略用於某個特定的查詢,為查詢發出一個解釋語句。如果你發現一個查詢使用廣播連線,當你知道透過基準,一個分割槽的連線將是更有效的,或反之亦然,向查詢新增一個提示,以指定使用精確的連線機制。在Impala的SELECT語句詳見查詢提示。

1.1.1  當統計數字不可用時如何處理

         如果表或列統計資訊不可用,在加入一些表,impala還是重新排序表使用資訊是可用的。表統計放在連線順序的左側,在成本遞減的順序,基於整體規模和基數。沒有統計的表被視為零大小,也就是說,它們總是放在連線順序的右邊。


1.1.2  straight_join連線順序大於其他

         如果Impala連線查詢是沒有效率的,過時的統計資料或意外的資料分佈,你可以把impala從排序連線表採用straight_join關鍵詞後立即選擇關鍵詞。的straight_join關鍵詞關閉重新加入條款,impala是內部,併產生一個依賴於加入條款被有序的最佳化查詢文字中的計劃。在這種情況下,重寫查詢,以便最大的表在左邊,其次是下一個最大的,等等,直到最小的表在右邊。

         在這個例子中,從大表的子查詢產生一個非常小的結果集,但表可能仍然被視為最大的連線順序放在第一。使用straight_join最後加入條款阻止最終的表被重新排序,使其在最右邊的表的連線順序。

selectstraight_join x from medium join small join (select * from big where c1 <10) as big

  where medium.id = small.id and small.id =big.id;

1.1.3  連線順序最佳化例項

        這裡的實際例子從側面證明:調整Impala的最簡單的方法連線查詢是收集統計每個表參與聯接的計算統計表。

         這裡有示例顯示在表之間有10億、2億和100萬行的連線。(在這種情況下,表沒有分割槽和使用Parquet 格式。)小表包含從最大的一個資料子集,對加入的唯一ID列方便。最小的表只包含從其他表中的列的子集。

[localhost:21000]> create table big stored as parquet as select * from raw_data;

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

|summary                    |

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

| Inserted1000000000 row(s) |

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

|||Returned1 row(s) in 671.56s

[localhost:21000]> desc big;

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

| name      | type   | comment |

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

| id        | int     |        |

| val       | int    |         |

|zfill     | string  |        |

| name      | string |         |

| assertion| boolean |         |

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

Returned 5row(s) in 0.01s

 [localhost:21000] > create table mediumstored as parquet as select * from big limit 200 * floor(1e6);

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

|summary                   |

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

| Inserted200000000 row(s) |

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

|Returned 1row(s) in 138.31s

[localhost:21000]> create table small stored as parquet as select id,val,name from big whereassertion = true limit 1 * floor(1e6);

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

|summary                 |

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

| Inserted1000000 row(s) |

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

|Returned 1row(s) in 6.32s

        對於任何一種效能試驗,使用EXPLAIN語句看到任何昂貴的查詢將不進行實際執行,使冗長的解釋計劃包含更注重效能的細節:最有趣的計劃線路以粗體突出顯示,顯示沒有連線表統計,impala不能在處理各階段涉及的行數的一個很好的估計,並可能堅持廣播加入機制,將一張表完全複製到每個節點。

[localhost:21000]> set explain_level=verbose;

EXPLAIN_LEVELset to verbose

[localhost:21000]> explain select count(*) from big join medium where big.id = medium.id;

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

| ExplainString                                          |

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

| EstimatedPer-Host Requirements: Memory=2.10GB VCores=2 |

|                                                         |

| PLANFRAGMENT 0                                          |

|   PARTITION: UNPARTITIONED                               |

|                                                         |

|   6:AGGREGATE (merge finalize)                           |

|   | output: SUM(COUNT(*))                               |

|   | cardinality: 1                                      |

|   | per-host memory: unavailable                        |

|   | tuple ids: 2                                        |

|   |                                                     |

|   5:EXCHANGE                                             |

|      cardinality: 1                                      |

|      per-host memory: unavailable                        |

|      tuple ids: 2                                        |

|                                                         |

| PLANFRAGMENT 1                                          |

|   PARTITION: RANDOM                                      |

|                                                         |

|   STREAM DATA SINK                                       |

|     EXCHANGE ID: 5                                       |

|     UNPARTITIONED                                        |

|                                                         |

|   3:AGGREGATE                                            |

|   | output: COUNT(*)                                    |

|   | cardinality: 1                                      |

|   | per-host memory: 10.00MB                            |

|   | tuple ids: 2                                        |

|   |                                                     |

|   2:HASH JOIN                                            |

|   |  joinop: INNER JOIN (BROADCAST)                    |

|   | hash predicates:                                    |

|   |   big.id = medium.id                                |

|  |  cardinality: unavailable                            |

|   | per-host memory: 2.00GB                             |

|   | tuple ids: 0 1                                      |

|   |                                                     |

|   |----4:EXCHANGE                                        |

|   |      cardinality: unavailable                       |

|   |      per-host memory: 0B                            |

|   |      tuple ids: 1                                   |

|   |                                                     |

|   0:SCAN HDFS                                            |

|     table=join_order.big #partitions=1/1 size=23.12GB   |

|     table stats: unavailable                            |

|     column stats: unavailable                           |

|     cardinality: unavailable                            |

|      per-host memory: 88.00MB                            |

|      tuple ids: 0                                        |

|                                                         |

| PLANFRAGMENT 2                                          |

|   PARTITION: RANDOM                                      |

|                                                         |

|   STREAM DATA SINK                                       |

|     EXCHANGE ID: 4                                       |

|     UNPARTITIONED                                        |

|                                                         |

|   1:SCAN HDFS                                            |

|     table=join_order.medium #partitions=1/1 size=4.62GB |

|     table stats: unavailable                            |

|     column stats: unavailable                           |

|      cardinality:unavailable                            |

|      per-host memory: 88.00MB                            |

|      tuple ids: 1                                        |

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

Returned 64row(s) in 0.04s

收集所有表的統計資料是簡單的,一個計算每表的計算統計語句:

[localhost:21000]> compute stats small;

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

|summary                                 |

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

| Updated 1partition(s) and 3 column(s). |

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

|Returned 1row(s) in 4.26s

[localhost:21000]> compute stats medium;

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

|summary                                 |

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

| Updated 1partition(s) and 5 column(s). |

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

|Returned 1row(s) in 42.11s

[localhost:21000]> compute stats big;

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

|summary                                 |

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

| Updated 1partition(s) and 5 column(s). |

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

|Returned 1row(s) in 165.44s

使用統計資訊,Impala可以選擇更有效的連線順序而不是從左到右的順序查詢中的表,並可選擇廣播或分割槽的基礎上加入整體尺寸和表中的行數的策略:

[localhost:21000]> explain select count(*) from medium join big where big.id = medium.id;

Query:explain select count(*) from medium join big where big.id = medium.id

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

| ExplainString                                            |

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

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

|                                                           |

| PLANFRAGMENT 0                                           |

|   PARTITION: UNPARTITIONED                                |

|                                                          |

|   6:AGGREGATE (merge finalize)                            |

|   | output: SUM(COUNT(*))                                |

|   | cardinality: 1                                       |

|   | per-host memory: unavailable                         |

|   | tuple ids: 2                                         |

|   |                                                      |

|   5:EXCHANGE                                              |

|      cardinality: 1                                       |

|      per-host memory: unavailable                         |

|      tuple ids: 2                                         |

|                                                          |

| PLANFRAGMENT 1                                           |

|   PARTITION: RANDOM                                       |

|                                                          |

|   STREAM DATA SINK                                        |

|     EXCHANGE ID: 5                                        |

|     UNPARTITIONED                                         |

|                                                           |

|   3:AGGREGATE                                             |

|   | output: COUNT(*)                                     |

|   | cardinality: 1                                       |

|   | per-host memory: 10.00MB                             |

|   | tuple ids: 2                                         |

|   |                                                      |

|   2:HASH JOIN                                             |

|   | join op: INNER JOIN (BROADCAST)                      |

|   | hash predicates:                                     |

|   |   big.id = medium.id                                 |

|   | cardinality: 1443004441                              |

|   | per-host memory: 839.23MB                            |

|   | tuple ids: 1 0                                       |

|   |                                                      |

|   |----4:EXCHANGE                                         |

|   |      cardinality: 200000000                          |

|   |      per-host memory: 0B                             |

|   |      tuple ids: 0                                    |

|   |                                                      |

|   1:SCAN HDFS                                             |

|      table=join_order.big #partitions=1/1size=23.12GB    |

|      table stats: 1000000000 rows total                   |

|      column stats: all                                    |

|      cardinality: 1000000000                              |

|      per-host memory: 88.00MB                             |

|      tuple ids: 1                                         |

|                                                          |

| PLANFRAGMENT 2                                           |

|   PARTITION: RANDOM                                       |

|                                                          |

|   STREAM DATA SINK                                        |

|     EXCHANGE ID: 4                                        |

|     UNPARTITIONED                                         |

|                                                          |

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

相關文章