sparkSQL可以指定分區字段為varchar類型嗎
首先我們可以查到,Hive從0.12.0版本就支持varchar類型作為列的類型了,但是sparkSQL可以指定分區字段為varchar類型嗎?我們可以先實驗一下。首先我們嘗試創建一個分區字段為varchar類型的表,執行語句如下:CREATE TABLE test0901222(LIST_RES_ID STRING, age Int) PARTITIONED BY (DATA_DATE VARCHAR(8)),然后發現是可以創建成功的,如下圖所示:
然后嘗試在這個表上以分區字段作為條件進行查詢,執行語句:select * from test0818222 where DATA_DATE = '20210428'。執行后發現有很奇怪的報錯,如下圖所示:
這是怎么回事呢?查看spark內核代碼找到相關代碼如下圖所示:
問題就出在getPartitionsByFilter這個方法中。可以看到這里是用反射的方法獲取filter的信息的,但是hive的官方文檔明確指出,使用反射的方法獲取varchar類型信息是不支持的,如下圖所示:
那么我們沒有辦法支持varchar作為分區字段了嗎,也不是的。讓我們回到上面的spark內核代碼,可以發現如果tryDirectSql如果為false時,getPartitionsByFilter會跳過filter然后回退到返回所有的分區(當然這樣會顯著的降低性能)。那么tryDirectSql又是什么呢,tryDirectSql是hive的配置,配置項為hive.metastore.try.direct.sql,主要控制Metastore 是否應該嘗試使用SQL直接查詢存儲路徑。
但是spark內核是否回退到不使用filter的行為依賴hive的參數配置是不合理的,如果我們希望把hive.metastore.try.direct.sql設置為true的同時(這樣設置在某些場景下可以提高性能)又希望getPartitionsByFilter執行失敗會回退到不使用filter就無法實現了。搜索后發現其實針對這個問題開源社區是有修改的,MR鏈接:https://github.com/apache/spark/pull/33382。
可以看到如果spark內核改為依賴自己內部的參數如shouldFallback就不會出現上述的問題了。這樣spark可以自己指定filter執行失敗后是否回退或者直接拋出異常。
根據以上分析,我們可以總結結論如下:
sparkSQL不是一定不可以指定分區字段為varchar類型的,根據不同的版本不同的配置參數理論上分析有可能是可行的。
由于varchar不支持反射獲取所以getPartitionsByFilter中一定會執行報錯,如果走回退的分支的話會顯著的降低性能。所以從性能的角度來分析即使可行也不推薦指定varchar類型作為分區字段,推薦可以根據不同的場景選擇String、Int等類型作為分區字段。
spark
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。