SPARK SQLいくつかのピット


現在のspark sqlプログラミングではscala apiおよびjava apiの方式が一般的であり、spark sql文を直接使用するよりもspark apiの方が柔軟であり、datasetおよびrddの2つの方式に基づいて操作することができるが、spark sqlのピットは少し多い.
1,getClass.getResourceAsStreamというクラスは、ネット上では通常「/」を付けないで現在のパッケージから読み取る、「/」を付けたのはルートclassパスから読み取ると言われていますが、ルートパスはideaやファイルの下に見えるsrc/main/resource/のようなパスではなく、最終的にパッケージ化されたときに生成されたjarのときのフォーマットで、jarが生成されたときにresourceフォルダの下でルートパスの下に展開され、だからresourceの下のリソースをロードするには、「/リソース名」だけでいいです.
2、select crossInfo, split(crossInfo, '|') as jda from tem_test_yy lateral view explode(split(jdaList, '#')) tmpTable as crossInfo
この文にはバグがあり、返された結果は
jda1|1|time1    ["j","d","a","1","|","1","|","t","i","m","e","1",""] jda1|1|time1    ["j","d","a","1","|","1","|","t","i","m","e","1",""] jda2|1|time2    ["j","d","a","2","|","1","|","t","i","m","e","2",""] |jda3|0|time3   ["|","j","d","a","3","|","0","|","t","i","m","e","3",""]
主な原因はhiveの中で|文字はエスケープ記号を使います!!正しい使い方はsplit(crossInfo,'|');
3、spark persistは乱用できない、特に
MEMORY_AND_DISK_SER

レベルは、大きなテーブルではpersist効率がよりはるかに低いです.数十億レベルのテーブルでは、効率を数倍に削減できます.
4、dataframe=dataset[row]、spark map内の匿名関数の戻り値はdataset[row]ではなく、そうでなければパケットシーケンス化エラーが発生し、dataset[class]の形式のみをサポートし、戻り後driver側でdataset[row]を通過する必要がある.toDF()はdataframeつまりdataset[row]に移行します.ただしdataset[row]はmapの入力として使用できます.
5、scala selet("_1.*")とselect($"_1")は、Tuple[_1,_2]タイプのdatasetを処理している場合、
後者は次のようなschemaを生成します.
|-- _1: struct (nullable = true)  |    |-- all_jda: string (nullable = true)  |    |-- user_visit_ip: string (nullable = true)  |    |-- sequence_num:integer(nullable=true)前者は次のようなschemaを生成する
 | -- all_jda: string (nullable = true)  | -- user_visit_ip: string (nullable = true)  | -- sequence_num: integer (nullable = true)
これは絶対に穴=.=,後者は複数のschema構造を持ち、spark sql文では非最上位の列に直接取り出すことができます.
6、spark sqlのいくつかの問題
(1)、hiveは正規文の使用をサポートし、spark sqlは(2)、left out join on A.column=B.columnはleft out join on columnと書くことができない.(3),select*from A left out join B on cloumn ambigiousエラーになるので注意(4),concat_wsはString以外のタイプの配列への接続をサポートしていません.udfを自分で実現する必要があります.