SQL 分析端點效能考量

SQL 分析端點讓你能利用 T-SQL 語言和 TDS 協定查詢湖屋中的資料。

Tip

關於優化 Delta 資料表以滿足 SQL 分析端點消耗的完整跨工作負載指引,包括檔案大小與列群組建議,請參閱 跨工作負載資料表維護與優化

每個 Lakehouse 都有一個 SQL 分析端點。 工作區中的 SQL 分析端點數目符合該工作區中佈建的 Lakehouse鏡像資料庫數目。

背景程序負責掃描湖屋中的變更,並使 SQL 分析端點保持最新狀態,以反映工作區中提交至各湖屋的所有變更。 Microsoft Fabric 平台透明地管理同步流程。 在 Lakehouse 中偵測到變更時,幕後處理會更新中繼資料,而 SQL 分析端點會反映已提交至 Lakehouse 資料表的變更。 在正常運作條件下,Lakehouse 與 SQL 分析端點之間的延隔時間小於一分鐘。 實際時間長度可能從幾秒到幾分鐘不等,取決於本文所討論的多種因素。 背景程序僅在 SQL 分析端點啟用時執行,且在 15 分鐘不活躍後停止。

Guidance

  • 自動中繼資料探索可追蹤提交至 Lakehouse 的變更,並在每個 Fabric 工作區中作為獨立實例存在。 如果你觀察到湖屋與 SQL 分析端點同步變更延遲增加,可能是因為同一工作區有大量湖屋。 在這種情況下,可以考慮將每個湖屋遷移到獨立的工作區,因為這種方式能讓自動元資料發現更為可擴展。
  • 依設計,Parquet 檔案是不可變的。 當有更新或刪除操作時,Delta 表格會隨變更集新增 Parquet 檔案,隨時間增加檔案數量,取決於更新與刪除的頻率。 如果你不安排維護作業,這種模式最終會造成讀取開銷,而這種情況會影響將變更同步至 SQL 分析端點所需的時間。 若要解決此問題,請安排定期Lakehouse 資料表維護作業
  • 在某些情況下,你可能會發現提交至資料湖倉的變更在相關的 SQL 分析端點中無法看到。 舉例來說,你可能在 lakehouse 建立一個新資料表,但它還沒列入 SQL 分析端點。 或者,您可能會將大量資料列提交至湖屋中的資料表,但這些資料在 SQL 分析端點中仍尚不可見。 你確實可以選擇 啟動隨選的元資料同步
  • 自動同步流程並不支援所有 Delta 功能。 如需 Fabric 中每個引擎所支援功能的詳細資訊,請參閱 Delta Lake 數據表格式互作性
  • 如果在擷取、轉換與載入(ETL)處理過程中有極大量的表格變更,預期會有一個延遲,直到所有變更都處理完畢。

優化 lakehouse 資料表以提升 SQL 分析端點的查詢效能

當 SQL 分析端點讀取儲存在湖屋中的資料表時,查詢效能高度依賴底層 Parquet 檔案的實體佈局。

大量小型 Parquet 檔案會產生開銷,並負面影響查詢效能。 為確保可預測且有效率的效能,應維持資料表儲存,使每個 Parquet 檔案包含兩百萬筆資料列。 這種列數提供了平衡的平行性,且不會將資料集分割成過小的切片。

除了列數指引外,檔案大小同樣重要。 SQL 分析端點在 Parquet 檔案足夠大以降低檔案處理負擔,但又不會過大以致影響平行掃描效率時表現最佳。 對大多數工作負載來說,將 Parquet 檔案保持在接近 400 MB 是最佳平衡點。 為了達到這種平衡,請採取以下步驟:

  1. 資料變更前設定 maxRecordsPerFile 為 2,000,000。
  2. 執行資料變更(資料擷取、更新、刪除)。
  3. 設定 maxFileSize 為 4 GB。
  4. 執行 OPTIMIZE。 如需使用 OPTIMIZE 的詳細資訊,請參閱 從 Lakehouse 執行資料表維護

以下腳本提供了這些步驟的範本,應在湖屋中執行:

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", 4 * 1024 * 1024 * 1024)

# 4. RUN OPTIMIZE (bin-packing)
spark.sql("""
    OPTIMIZE myTable
""")

為了維持適當的檔案大小,應定期執行 Delta 最佳化作業,例如 OPTIMIZE,尤其是對於經常接收增量插入、更新和刪除的資料表。 這些維護作業將小檔案壓縮成適當大小的檔案,確保 SQL 分析端點能有效處理查詢。

Note

如需有關 Lakehouse 資料表一般維護的指引,請參閱 從 Lakehouse 執行資料表維護

分割區大小考量

Lakehouse 中 Delta 資料表的分割區資料行選擇也會影響將變更同步至 SQL 分析端點所需的時間。 分割區資料行的分割區數目和大小對於效能而言很重要:

  • 具有高基數的資料行 (主要或完全由唯一值組成) 會導致大量的分割區。 大量分割區會對中繼資料探索掃描變更的效能造成負面影響。 如果資料行的基數很高,請選擇另一個資料行來進行資料分割。
  • 每個分割區的大小也會影響效能。 使用可產生至少 1 GB(或接近 1 GB)分割區的欄位。 遵循 Delta 資料表維護最佳化的最佳做法。 關於評估分割區的Python腳本,請參見 Sample script 以了解分割細節

大量的小型 parquet 檔案會使在 Lakehouse 與其關聯的 SQL 分析端點之間進行同步變更所需的時間增加。 基於一或多個原因,您最終可能會在 Delta 資料表中產生大量的 Parquet 檔案:

  • 如果你為一個 Delta 資料表選擇一個有大量唯一值的分割區,該資料表會依每個唯一值被劃分,可能會被過度分割。 選擇基數不高的分區欄位,並確保每個分區至少為 1 GB。
  • 批次和串流資料的擷取速率可能會導致小型檔案生成,這取決於變更的頻率和寫入至 Lakehouse 時的變更大小。 例如,湖邊別墅可能有少量變更,導致小型拼花板銼。 為了解決這個問題,請定期執行 Lakehouse 資料表維護

分割區詳細資料的範例指令碼

使用以下筆記本列印一份報告,其中詳細說明支援 Delta 資料表的分割區的大小和詳細資料。

  1. 首先,在變數 delta_table_path中提供 delta 表的 ABFSS 路徑。
    • 您可以從 Fabric 入口網站的瀏覽器取得 Delta 資料表的 ABFSS 路徑。 以滑鼠右鍵按一下資料表名稱,然後從選項清單中選取 COPY PATH
  2. 指令碼會輸出 Delta 資料表的所有分割區。
  3. 指令碼會逐一查看每個分割區,以計算檔案的總大小和數目。
  4. 指令碼會輸出分割區的詳細資料、每個分割區的檔案,以及每個分割區的大小 (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']}")

Lakehouse 中的 SQL 分析端點會自動產生結構描述

針對 Lakehouse 中的每個 Delta 數據表,SQL 分析端點會自動在適當的架構中產生數據表。 SQL 分析端點引擎是基於 Fabric Data Warehouse 引擎。

欲了解更多資訊,請參閱 SQL 分析端點元資料同步。你也可以透過 Refresh SQL 端點的 REST API 強制自動刷新元資料掃描。