ImpalaでTPC-Hを動かすためのSQL書き換え
TPC-H on HiveをImpalaで動くようになるまでの変更箇所をまとめておきます.
Impalaでは実行できないHiveQLを調べるときの参考になると思います.
DDLは実行できない
ImpalaのLanguage Referenceにも書かれています.
そこでDROPやCREATE文は別ファイルにしておき,Hive上で実行します.
対象クエリ: 全て
ORDER BYにはLIMIT必須
LIMIT付けないとこんなのが出ます.こちらも前述のリファレンスに書かれています.
ERROR: com.cloudera.impala.common.NotImplementedException: ORDER BY without LIMIT currently not supported
じゃあ,付ければいいんだろということで付けました.
-- Q1の変更例 SELECT ... ORDER BY L_RETURNFLAG, L_LINESTATUS LIMIT 2147483647;
実は,ImpalaはLIMIT 9223372036854775807(符号付きint64 max)としても動きます.
今回はHiveでも動作するようにしたかったので,int32 maxとしました.
対象クエリ: Q1, Q4, Q5, Q7, Q8, Q9, Q12, Q15, Q16, Q20
GROUP BYには浮動小数点が使えない
doubleとかを指定しようとするとこんなのが出ます.
ERROR: com.cloudera.impala.common.AnalysisException: GROUP BY expression must have a discrete (non-floating point) type: c_acctbal (in insert overwrite table q10_returned_item
仕方ないので一度1000倍してintにし,最終的に1000で割るという無茶をしています.
有効数字?なにそれおいしいの.
-- Q10の変更例 select ... cast(c_acctbal*1000 as int)/1000, n_name, c_address, c_phone, c_comment from ... group by c_custkey, c_name, cast(c_acctbal*1000 as int), c_phone, n_name, c_address, c_comment ...
対象クエリ: Q10, Q18
CROSS JOINができない
こいつが一番やっかいです.JOINするには,必ず結合条件を書かなければいけないようです.
ERROR: com.cloudera.impala.common.NotImplementedException: Join requires at least one equality predicate between the two tables.
Q7の場合はn_regionkeyを使うことで結果的にうまくいったのですが,Q11とQ22では回避できず断念しました.
(Q7は'FRANCE'と'GERMANY'のn_regionkeyがたまたま同じでごまかせただけで,本当は解決していません)
-- Q7の変更例 select ... from nation n1 join nation n2 on -- ここから n1.n_regionkey = n2.n_regionkey and -- ここまでを追加 n1.n_name = 'FRANCE' and n2.n_name = 'GERMANY' ...
対象クエリ: Q7, Q11, Q22
その他
HiveでDDLを実行した場合,impalaではrefreshコマンドによる反映が必要です.
↓のようにするとよいでしょう.
impala-shell --impalad=ip_address:port -q 'refresh'