在 Azure Synapse Analytics 中使用無伺服器 SQL 集區,查詢以 Delta Lake 檔案

在本文中,您將瞭解如何使用無伺服器 Synapse SQL 集區撰寫查詢,以讀取 Delta Lake 檔案。 Delta Lake 是開放原始碼儲存層,可將 ACID (不可部分完成性、一致性、隔離和持久性)交易帶入 Apache Spark 和巨量資料工作負載。 您可以從如何查詢 Delta Lake 資料表影片 中深入瞭解

Synapse 工作區中的無伺服器 SQL 集區可讓您讀取以 Delta Lake 格式儲存的資料,並將其用於報告工具。 無伺服器 SQL 集區可以讀取使用 Apache Spark、Azure Databricks 或任何其他 Delta Lake 格式產生者所建立的 Delta Lake 檔案。

Azure Synapse 中的 Apache Spark 集區可讓資料工程師使用 Scala、PySpark 和 .NET 修改 Delta Lake 檔案。 無伺服器 SQL 集區可協助資料分析師在資料工程師所建立的 Delta Lake 檔案上建立報告。

重要

使用無伺服器 SQL 集區查詢 Delta Lake 格式是 正式運作 的功能。 不過,查詢 Spark Delta 資料表仍處於公開預覽狀態,但尚未準備好生產環境。 如果您查詢使用 Spark 集區建立的 Delta 資料表,可能會發生已知問題。 請參閱無伺服器 SQL 集區自助 中的 已知問題。

快速入門範例

OPENROWSET 式可讓您藉由提供根資料夾的 URL 來讀取 Delta Lake 檔案的內容。

讀取 Delta Lake 資料夾

查看檔案 DELTA 內容最簡單的方式是提供 OPENROWSET 函式的 檔案 URL 並指定 DELTA 格式。 如果檔案可供公開使用,或您的 Microsoft Entra 身分識別可以存取此檔案,您應該可以使用如下列範例所示的查詢來查看檔案的內容:

SELECT TOP 10 *
FROM OPENROWSET(
    BULK 'https://sqlondemandstorage.blob.core.windows.net/delta-lake/covid/',
    FORMAT = 'delta') as rows;

資料行名稱和資料類型會自動從 Delta Lake 檔案讀取。 函 OPENROWSET 式會針對字串資料行使用最佳猜測類型,例如 VARCHAR(1000)。

函式 OPENROWSET 中的 URI 必須參考根 Delta Lake 資料夾,其中包含名為 _delta_log 的子資料夾。

ECDC COVID-19 Delta Lake folder

如果您沒有此子資料夾,則不會使用 Delta Lake 格式。 您可以使用下列 Apache Spark Python 腳本,將資料夾中的一般 Parquet 檔案轉換成 Delta Lake 格式:

%%pyspark
from delta.tables import DeltaTable
deltaTable = DeltaTable.convertToDelta(spark, "parquet.`abfss://delta-lake@sqlondemandstorage.dfs.core.windows.net/covid`")

若要改善查詢的效能,請考慮在 子句 WITH 指定明確類型。

注意

無伺服器 Synapse SQL 集區會使用架構推斷來自動判斷資料行及其類型。 架構推斷的規則與 Parquet 檔案所使用的規則相同。 針對 Delta Lake 類型對應至 Parquet 的 SQL 原生類型檢查 類型對應。

請確定您可以存取檔案。 如果您的檔案受到 SAS 金鑰或自訂 Azure 身分識別的保護,您必須設定 SQL 登入 的伺服器層級認證。

重要

請確定您使用的是 UTF-8 資料庫定序(例如 Latin1_General_100_BIN2_UTF8 ),因為 Delta Lake 檔案中的字串值會使用 UTF-8 編碼進行編碼。 Delta Lake 檔案中的文字編碼與定序不符可能會導致非預期的轉換錯誤。 您可以使用下列 T-SQL 語句,輕鬆地變更目前資料庫的預設定序:ALTER DATABASE CURRENT COLLATE Latin1_General_100_BIN2_UTF8; 如需定序的詳細資訊,請參閱 Synapse SQL 支援的定序類型。

資料來源使用量

上述範例使用檔案的完整路徑。 或者,您可以使用指向儲存體根資料夾的位置來建立外部資料源。 建立外部資料源之後,請使用資料來源和函式中檔案的 OPENROWSET 相對路徑。 如此一來,您就不需要使用檔案的完整絕對 URI。 您也可以接著定義自訂認證來存取儲存體位置。

重要

資料來源只能在自訂資料庫中建立(不在 master 資料庫或從 Apache Spark 集區複寫的資料庫)。

若要使用下列範例,您必須完成下列步驟:

  1. 使用參考 NYC 黃色計程車 儲存體帳戶的資料來源建立資料庫
  2. 在步驟 1 中建立的資料庫上執行 安裝腳本 ,以初始化 物件。 此設定腳本會建立這些範例中使用的資料來源、資料庫範圍認證和外部檔案格式。

如果您已建立資料庫,並將內容切換至資料庫(使用 USE database_name 語句或下拉式清單來選取某些查詢編輯器中的資料庫),您可以建立包含資料集根 URI 的外部資料源,並用它來查詢 Delta Lake 檔案:

CREATE EXTERNAL DATA SOURCE DeltaLakeStorage
WITH ( LOCATION = 'https://sqlondemandstorage.blob.core.windows.net/delta-lake/' );
GO

SELECT TOP 10 *
FROM OPENROWSET(
        BULK 'covid',
        DATA_SOURCE = 'DeltaLakeStorage',
        FORMAT = 'delta'
    ) as rows;

如果使用 SAS 金鑰或自訂身分識別來保護資料來源,您可以使用資料庫範圍認證來設定資料來源

明確指定架構

OPENROWSET 可讓您明確指定要使用 子句從檔案 WITH 讀取的資料行:

SELECT TOP 10 *
FROM OPENROWSET(
        BULK 'covid',
        DATA_SOURCE = 'DeltaLakeStorage',
        FORMAT = 'delta'
    )
    WITH ( date_rep date,
           cases int,
           geo_id varchar(6)
           ) as rows;

使用結果集架構的明確規格,您可以將類型大小降到最低,並針對字串資料行使用更精確的 VARCHAR(6) 類型,而不是悲觀的 VARCHAR(1000)。 類型的最小化可能會大幅改善查詢的效能。

重要

請確定您明確為 子句中的所有 WITH 字串資料行指定 UTF-8 定序, Latin1_General_100_BIN2_UTF8 或在資料庫層級設定 UTF-8 定序。 檔案中的文字編碼與字串資料行定序之間的不符可能會導致非預期的轉換錯誤。 您可以使用下列 T-SQL 語句,輕鬆地變更目前資料庫的預設定序:alter database current collate Latin1_General_100_BIN2_UTF8 您可以使用下列定義,輕鬆地在 Colum 類型上設定定序: geo_id varchar(6) collate Latin1_General_100_BIN2_UTF8

資料集

此範例會使用 NYC 黃色計程車 資料集。 原始 PARQUET 資料集會 DELTA 轉換成格式,並在 DELTA 範例中使用版本。

查詢分割區的資料

此範例中提供的資料集會分割為不同的子資料夾(分割)。

不同于 Parquet ,您不需要使用 函 FILEPATH 式以特定分割區為目標。 OPENROWSET會識別 Delta Lake 資料夾結構中的資料分割資料行,並可讓您使用這些資料行直接查詢資料。 此範例顯示 2017 年前三個月依年、月和payment_type的票價金額。

SELECT
        YEAR(pickup_datetime) AS year,
        passenger_count,
        COUNT(*) AS cnt
FROM  
    OPENROWSET(
        BULK 'yellow',
        DATA_SOURCE = 'DeltaLakeStorage',
        FORMAT='DELTA'
    ) nyc
WHERE
    nyc.year = 2017
    AND nyc.month IN (1, 2, 3)
    AND pickup_datetime BETWEEN CAST('1/1/2017' AS datetime) AND CAST('3/31/2017' AS datetime)
GROUP BY
    passenger_count,
    YEAR(pickup_datetime)
ORDER BY
    YEAR(pickup_datetime),
    passenger_count;

OPENROWSET 式將會消除不符合 where year 子句 中 和 month 的資料分割。 此檔案/資料分割剪除技術可大幅減少資料集、改善效能,以及降低查詢成本。

函式中的資料夾名稱 ( yellow 在此範例中) 會使用 LOCATION 資料來源中的 OPENROWSETDeltaLakeStorage 串連,而且必須參考包含名為 _delta_log 之子資料夾的根 Delta Lake 資料夾。

Yellow Taxi Delta Lake folder

如果您沒有此子資料夾,則不會使用 Delta Lake 格式。 您可以使用下列 Apache Spark Python 腳本,將資料夾中的一般 Parquet 檔案轉換成 Delta Lake 格式:

%%pyspark
from delta.tables import DeltaTable
deltaTable = DeltaTable.convertToDelta(spark, "parquet.`abfss://delta-lake@sqlondemandstorage.dfs.core.windows.net/yellow`", "year INT, month INT")

函式的第 DeltaTable.convertToDeltaLake 二個引數代表屬於資料夾模式 year=*/month=* 的分割資料行(年和月),以及其類型。

限制

下一步

請前進到下一篇文章,以 瞭解如何查詢 Parquet 巢狀類型 。 如果您想要繼續建置 Delta Lake 解決方案,請瞭解如何在 Delta Lake 資料夾中建立 檢視 外部資料表

另請參閱