2017-07-03 3 views
0

配列から値をフィルタリングしようとしています。値は保持すべき情報は別のテーブルにあります。現時点では他のテーブルに依存するフィルタ配列

output 
________________________ 
| id | filtered_values | 
------------------------ 
| 1 | [b]    | 
| 2 | [e, f]   | 
| 3 | []    | 
------------------------ 

、私は次のクエリを使用しています:

table_a      table_b 
___________________   ___________ 
| id | values  |   | keyword | 
-------------------   ----------- 
| 1 | [a, b, c] |   | b | 
| 2 | [d, e, f] |   | e | 
| 3 | [a, g]  |   | f | 
-------------------   ----------- 

私は次の出力を期待

SELECT 
    id, 
    array_intersect(ta.values, tb.filter_keywords) AS filtered_values -- brickhouse UDF 
FROM 
    table_a ta 
CROSS JOIN (
    SELECT 
    collect_set(keyword) as filter_keywords 
    FROM (
    SELECT 
     "dummy" as grouping_dummy, 
     keyword 
    FROM 
     table_b 
) tmp 
    GROUP BY 
    grouping_dummy 
) 

table_aはカップル万行を持って、table_bは1000の未満の行が含まれています。 1つのレデューサーしか使用していないので、クロス結合がボトルネックになっていると思います。

このクエリを最適化する方法はありますか?

ありがとうございます!

答えて

0

私は別の仮定を持っています。

マップサイド操作であるCROSS JOINではなく、filter_keywordsを生成するためにレデューサが必要です。
ここに問題はありません。

私の推測では、パフォーマンスの低下が1000個の要素の配列でarray_intersectの使用から来ることで、そのための解決策は、それを回避することでしょう。

p.s.
grouping_dummyの必要はありません。
は、集計関数を使用するためにGROUP BYを使用する必要はありません。

select  a.id 
      ,collect_list (case when b.keyword is not null then a.val end) as vals 


from  (select a.id 
        ,e.val 

      from table_a a 

         lateral view outer 

          explode (a.vals) e as val 
      ) a 

      left join table_b b 

      on   b.keyword = 
         a.val 

group by a.id 

+----+-----------+ 
| id | vals | 
+----+-----------+ 
| 1 | ["b"]  | 
| 2 | ["e","f"] | 
| 3 | []  | 
+----+-----------+ 
+0

チェック更新の回答 –

関連する問題