適用於:✅Microsoft Fabric 中的 SQL 分析端點
SQL 分析端點可讓您使用 T-SQL 語言和 TDS 通訊協定,查詢 Lakehouse 中的資料。
小提示
關於優化 Delta 資料表以滿足 SQL 分析端點消耗的完整跨工作負載指引,包括檔案大小與列群組建議,請參閱 跨工作負載資料表維護與優化。
每個 Lakehouse 都有一個 SQL 分析端點。 工作區中的 SQL 分析端點數目符合該工作區中佈建的 Lakehouse 和鏡像資料庫數目。
幕後處理負責掃描 Lakehouse 是否有變更,並將 SQL 分析端點保持在最新狀態,以取得工作區中所有提交至 Lakehouse 的變更。 同步處理程序會由 Microsoft Fabric 平台透明管理。 在 Lakehouse 中偵測到變更時,幕後處理會更新中繼資料,而 SQL 分析端點會反映已提交至 Lakehouse 資料表的變更。 在正常運作條件下,Lakehouse 與 SQL 分析端點之間的延隔時間小於一分鐘。 實際時間長度可能從幾秒到幾分鐘不等,取決於本文討論的多種因素。 背景程序只有在 SQL 分析端點活躍時才會執行,且在 15 分鐘不活躍後停止。
Lakehouse 中的 SQL 分析端點會自動產生結構描述
SQL 分析端點會管理自動產生的資料表,因此工作區使用者無法進行修改。 使用者可以藉由新增自己的 SQL 結構描述、檢視、程序和其他資料庫物件,來擴充資料庫模型。
針對 Lakehouse 中的每個 Delta 數據表,SQL 分析端點會自動在適當的架構中產生數據表。 如需 SQL 分析端點自動產生的結構描述資料類型,請參閱 Microsoft Fabric 中的資料類型。
在 SQL 分析端點中建立資料表會稍有延遲。 一旦你在湖中建立或更新 Delta Lake 資料表,參考該 Delta 湖資料表的 SQL 分析端點資料表就會自動建立或刷新。
重新整理資料表所需的時間量與 Delta 資料表的最佳化程度有關。 如需詳細資訊,請檢閱 Delta Lake 資料表最佳化和 V 順序 ,以深入了解重要案例,及有關如何有效率地維護 Delta 資料表以實現最大效能的深入指南。
您可以在 Fabric 入口網站中手動強制重新整理自動中繼資料掃描。 在 SQL 分析端點的頁面上,選取 [Explorer] 工具列中的 [重新整理] 按鈕,以更新結構。 移至 [查詢] 您的 SQL 分析端點,然後尋找 [重新整理] 按鈕,如下圖所示。
您也可以透過程式設計方式使用 SQL 端點元數據 REST API 來強制重新整理自動元數據掃描。
指引
- 自動中繼資料探索可追蹤提交至 Lakehouse 的變更,並在每個 Fabric 工作區中作為獨立實例存在。 如果您觀察到湖屋與 SQL 分析端點之間的同步變更延遲增加,這可能是由於在同一工作區中有大量的湖屋。 在這種情況下,請考慮將每個 Lakehouse 移轉至不同的工作區,因為這樣可以擴展自動中繼資料的探索能力。
- 依設計,Parquet 檔案是不可變的。 當有更新或刪除作業時,Delta 資料表會新增新的 Parquet 檔案與變更集,隨時間增加檔案數目,具體視更新和刪除的頻率而定。 如果沒有排程維護,此模式最終會產生讀取額外負荷,而這會影響將變更同步至 SQL 分析端點所需的時間。 若要解決此問題,請排程定期的 Lakehouse 資料表維護作業。
- 在某些情況下,你可能會發現提交至資料湖倉的變更在相關的 SQL 分析端點中無法看到。 例如,您可能已在 Lakehouse 中建立新的數據表,但尚未列在 SQL 分析端點中。 或者,你可能將大量資料列提交至 lakehouse 中的某個資料表,但這些資料尚未在 SQL 分析端點顯示出來。 建議您啟動隨需元數據同步處理,可從 SQL 查詢編輯器的 [重新整理] 功能區選項或 [SQL 端點元數據 REST API 的重新整理] 功能來觸發。 這個選項會強制隨選中繼資料同步,而不是等待背景中繼資料同步完成。
- 並非所有 Delta 特性都能被自動同步處理程序識別。 如需 Fabric 中每個引擎所支援功能的詳細資訊,請參閱 Delta Lake 數據表格式互作性。
- 如果在擷取、轉換與載入(ETL)處理過程中有極大量的資料表變更,可能會有預期的延遲,直到所有變更都處理完畢。
優化 lakehouse 資料表以提升 SQL 分析端點的查詢效能
當 SQL 分析端點讀取儲存在湖倉中的資料表時,查詢效能會受到底層 Parquet 檔案實體佈局的高度影響。
大量小型 Parquet 檔案會增加開銷,並且會對查詢效能產生不利影響。 為確保可預測且有效率的效能,我們建議維持資料表儲存,使每個parquet檔案包含兩百萬筆資料列。 這種列數提供了平衡的平行性,且不會將資料集分割成過小的切片。
除了列數指引外,檔案大小同樣重要。 SQL 分析端點在 parquet 檔案足夠大以降低檔案處理負擔,但又不會過大以限制平行掃描效率時表現最佳。 對大多數工作負載來說,將單一 Parquet 檔案保持在接近 400 MB 是最佳的平衡點。 為了達到這種平衡,請採取以下步驟:
- 設定
maxRecordsPerFile為 2,000,000 在資料變更前。 - 執行資料變更(資料擷取、更新、刪除)。
- 設定
maxFileSize為 4 GB。 - 執行
OPTIMIZE。 關於如何使用OPTIMIZE的細節,請參閱 資料表維護操作。
以下腳本提供了這些步驟的範本,應在湖屋中執行:
from delta.tables import DeltaTable
# 1. CONFIGURE LIMITS
# Cap files to 2M rows during writes. This should be done before data ingestion occurs.
spark.conf.set("spark.sql.files.maxRecordsPerFile", 2000000)
# 2. INGEST DATA
# Here, you ingest data into your table
# 3. CAP FILE SIZE (~4GB)
spark.conf.set("spark.databricks.delta.optimize.maxFileSize", 400 * 1024 * 1024 * 1024)
# 4. RUN OPTIMIZE (bin-packing)
spark.sql("""
OPTIMIZE myTable
""")
為維持檔案大小健康,使用者應定期執行 Delta 優化操作,如 OPTIMIZE,特別是對於經常有增量寫入、更新與刪除的資料表。 這些維護作業將小檔案壓縮成適當大小的檔案,確保 SQL 分析端點能有效處理查詢。
備註
關於湖屋表的一般維護指引,請參考 「使用 Lakehouse 即席執行 Delta 表維護」。
分割區大小考量
Lakehouse 中 Delta 資料表的分割區資料行選擇也會影響將變更同步至 SQL 分析端點所需的時間。 分割區資料行的分割區數目和大小對於效能而言很重要:
- 具有高基數的資料行 (主要或完全由唯一值組成) 會導致大量的分割區。 大量分割區會對中繼資料探索掃描變更的效能造成負面影響。 如果資料行的基數很高,請選擇另一個資料行來進行資料分割。
- 每個分割區的大小也會影響效能。 我們建議使用會導致分割區大小至少 (或接近) 1 GB 的欄。 我們建議遵循 Delta 資料表維護的最佳做法;最佳化。 如需評估分割區的 Python 指令碼,請參閱分割區詳細資料的範例指令碼。
大量的小型 parquet 檔案會使在 Lakehouse 與其關聯的 SQL 分析端點之間進行同步變更所需的時間增加。 基於一或多個原因,您最終可能會在 Delta 資料表中產生大量的 Parquet 檔案:
- 如果您為 Delta 資料表選擇具有大量唯一值的分割條件,那麼它會依據每個唯一值進行分割,此舉可能導致過度分割。 選擇基數不高的分區欄位,並確保每個分區至少為 1 GB。
- 批次和串流資料的擷取速率可能會導致小型檔案生成,這取決於變更的頻率和寫入至 Lakehouse 時的變更大小。 例如,湖邊別墅可能有少量變更,導致小型拼花板銼。 若要解決此問題,我們建議定期進行 lakehouse 資料表維護。
分割區詳細資料的範例指令碼
使用以下筆記本列印一份報告,其中詳細說明支援 Delta 資料表的分割區的大小和詳細資料。
- 首先,您必須在變數
delta_table_path中提供 Delta 資料表的 ABSFF 路徑。- 您可以從 Fabric 入口網站的瀏覽器取得 Delta 資料表的 ABFSS 路徑。 以滑鼠右鍵按一下資料表名稱,然後從選項清單中選取
COPY PATH。
- 您可以從 Fabric 入口網站的瀏覽器取得 Delta 資料表的 ABFSS 路徑。 以滑鼠右鍵按一下資料表名稱,然後從選項清單中選取
- 指令碼會輸出 Delta 資料表的所有分割區。
- 指令碼會逐一查看每個分割區,以計算檔案的總大小和數目。
- 指令碼會輸出分割區的詳細資料、每個分割區的檔案,以及每個分割區的大小 (GB)。
可以從下列程式碼區塊複製完整的指令碼:
# Purpose: Print out details of partitions, files per partitions, and size per partition in GB.
from notebookutils import mssparkutils
# Define ABFSS path for your delta table. You can get ABFSS path of a delta table by simply right-clicking on table name and selecting COPY PATH from the list of options.
delta_table_path = "abfss://<workspace id>@<onelake>.dfs.fabric.microsoft.com/<lakehouse id>/Tables/<tablename>"
# List all partitions for given delta table
partitions = mssparkutils.fs.ls(delta_table_path)
# Initialize a dictionary to store partition details
partition_details = {}
# Iterate through each partition
for partition in partitions:
if partition.isDir:
partition_name = partition.name
partition_path = partition.path
files = mssparkutils.fs.ls(partition_path)
# Calculate the total size of the partition
total_size = sum(file.size for file in files if not file.isDir)
# Count the number of files
file_count = sum(1 for file in files if not file.isDir)
# Write partition details
partition_details[partition_name] = {
"size_bytes": total_size,
"file_count": file_count
}
# Print the partition details
for partition_name, details in partition_details.items():
print(f"{partition_name}, Size: {details['size_bytes']:.2f} bytes, Number of files: {details['file_count']}")