詳情請參考Databricks官網文章:最佳實踐
本文介紹了使用Delta Lake時的最佳做法。
提供數據位置提示
如果您通常希望在查詢謂詞中使用一個列,并且該列具有較高的基數(即,大量不同的值),則使用Z-ORDER-BY。Delta-Lake根據列值自動布局文件中的數據,并在查詢時使用布局信息跳過不相關的數據。
有關詳細信息,請參見Z-Ordering(多維集群)。
選擇正確的分區列
您可以按列對Delta表進行分區。最常用的分區列是date。遵循以下兩個經驗法則來確定要按哪個分區進行分區:
如果列的基數很高,請不要使用該列進行分區。例如,如果按列進行分區,userId并且可以有1M個不同的用戶ID,則這是一個不好的分區策略。
每個分區中的數據量:如果您希望該分區中的數據至少為1 GB,則可以按列進行分區。
壓縮文件
如果您不斷將數據寫入Delta表,隨著時間的流逝,它將累積大量文件,尤其是如果您少量添加數據時。這可能會對表讀取的效率產生不利影響,也可能影響文件系統的性能。理想情況下,應定期將大量小文件重寫為少量大文件。這稱為壓縮。
您可以使用OPTIMIZE命令來壓縮表。
替換表的內容或架構
有時您可能要替換Delta表。例如:
您發現表中的數據不正確,并且想要替換內容。
您想要重寫整個表以進行不兼容的架構更改(刪除列或更改列類型)。
雖然您可以刪除Delta表的整個目錄并在同一路徑上創建新表,但不建議這樣做,因為:
刪除目錄效率不高。包含非常大文件的目錄可能要花費數小時甚至數天才能刪除。
您會丟失已刪除文件中的所有內容;如果刪除錯誤的表,將很難恢復。
目錄刪除不是原子的。在刪除表時,讀取表的并發查詢可能會失敗或看到部分表。
如果不需要更改表架構,則可以從Delta表中刪除數據并插入新數據,或者更新表以修復不正確的值。
如果要更改表架構,則可以atomic替換整個表。例如:
dataframe.write \
.format("delta") \
.mode("overwrite") \
.option("overwriteSchema", "true") \
.partitionBy(<your-partition-columns>) \
.saveAsTable("<your-table>") # Managed table
dataframe.write \
.format("delta") \
.mode("overwrite") \
.option("overwriteSchema", "true") \
.option("path", "<your-table-path>") \
.partitionBy(<your-partition-columns>) \
.saveAsTable("<your-table>") # External table
這種方法有很多好處:
覆蓋表的速度要快得多,因為它不需要遞歸列出目錄或刪除任何文件。
該表的舊版本仍然存在。如果刪除錯誤的表,則可以使用時間段輕松檢索舊數據。
這是一個原子操作。刪除表時,并發查詢仍然可以讀取表。
由于Delta Lake ACID事務保證,如果覆蓋表失敗,該表將處于其先前狀態。
另外,如果要在覆蓋表后刪除舊文件以節省存儲成本,則可以使用VACUUM刪除它們。它針對文件刪除進行了優化,通常比刪除整個目錄要快。