适用于: SQL Server 2016 (13.x) 及以后版本
Azure SQL 数据库
Azure SQL 托管实例
Microsoft Fabric 中的 SQL 数据库
数据虚拟化 允许对外部数据运行 Transact-SQL(T-SQL)查询,而无需将其加载到数据库中。 定义外部数据源、可选文件格式和外部表,然后使用任何其他表一样查询外部表 SELECT 。
本指南可帮助你:
- 了解您的 SQL 平台及其版本支持哪些 PolyBase 功能。
- 在查询或引入数据时,可在
OPENROWSET、外部表和BULK INSERT之间进行选择。 - 按照常见场景的分步链接操作。
- 查看生产工作负荷的性能、故障排除和最佳做法。
平台支持
- PolyBase 是 Microsoft SQL 数据库引擎 的一个功能,实现了数据虚拟化。
- PolyBase 在 Windows 上的 SQL Server 2016 及以后版本中得到支持,在 Linux 上的 SQL Server 2019 及以后版本中得到支持。
- Linux 版 SQL Server 2017 不支持 PolyBase。
- PolyBase 不支持 Azure SQL 数据库,但 Azure SQL 数据库 通过外部表提供相关的数据虚拟化功能
OPENROWSET。 有关详细信息,请参阅 Azure SQL 数据库的数据虚拟化(预览版)。 - Azure SQL 托管实例 中没有名为 PolyBase 的功能,但它具有运行方式类似的数据虚拟化功能。 有关详细信息,请参阅 Azure SQL 托管实例的数据虚拟化。
- PolyBase 在 Fabric 的 SQL 数据库中不被支持 ,但 Fabric 中的 SQL 数据库为 OneLake 中的数据提供了自己的数据虚拟化功能。 更多信息请参见 Fabric 中的 SQL 数据库中的数据虚拟化。
- PolyBase 不是 Fabric Data Warehouse 的一项功能。 对于 Fabric Data Warehouse 中的数据虚拟化,请考虑 Fabric OneLake Shortcuts。 关于Fabric Data Warehouse中的数据加载文章,请参见使用 T-SQL 和维度建模进行数据摄取:加载表。
常见用例
下表描述了可能的使用方案。
| 情景 | 使用 |
|---|---|
| 临时文件浏览 | OPENROWSET(BULK ...) |
| 用于 BI 或报表的可复用文件查询功能 | 基于文件的外部表 |
| 跨数据库查询 (SQL Server、Oracle、Teradata、MongoDB、ODBC) | 包含外部表的 PolyBase 连接器 |
| 将查询结果导出到文件 |
CREATE EXTERNAL TABLE AS SELECT (CETAS) |
| 批量引入到表中 |
BULK INSERT 或 OPENROWSET(BULK ...) 与 INSERT ... SELECT |
- 对于临时文件探索,可以使用
OPENROWSET(BULK ...)检查文件,而无需创建可重复使用表。 - 对于在BI或报告场景中的可复用文件查询,使用外部表覆盖文件以持久化模式并在查询间共享结果。
- 对于跨数据库查询,可以使用带有外部表的PolyBase连接器访问SQL Server、Oracle、Teradata、MongoDB或ODBC源代码。
- 如果要导出查询结果到文件,可以用
CREATE EXTERNAL TABLE AS SELECT(CETAS)在数据库外写入Parquet或CSV输出。 - 对于向表中批量导入数据,可以使用
BULK INSERT或OPENROWSET(BULK ...)配合INSERT ... SELECT将文件数据加载到数据库表中。
哪些功能可在何处使用?
下表显示了自 SQL Server 2019 起每个 SQL 平台上可用的 PolyBase 和数据虚拟化核心功能。 有关SQL Server 2016和SQL Server 2017在Windows上的可用性,请参见PolyBase的功能和限制。 使用此表来确定可以在平台上执行的操作,然后才能使用详细的指南。
| 功能 | SQL Server 2019 | SQL Server 2022 | SQL Server 2025 | Azure SQL 数据库 | Azure SQL 托管实例 | Microsoft Fabric 中的 SQL 数据库 |
|---|---|---|---|---|---|---|
| 外部表 | 是的 | 是的 | 是的 | 是的 | 是的 | 是的 |
| OPENROWSET (BULK) | 是 1 | 是的 | 是的 | 是的 | 是的 | 是的 |
| CETAS (导出) | 否 | 是的 | 是的 | 否 | 是的 | 否 |
| CSV/带分隔符的文件 | 是 2 | 是的 | 是的 | 是的 | 是的 | 是的 |
| Parquet 文件 | 否 | 是的 | 是的 | 是的 | 是的 | 是的 |
| Delta Lake 表 | 否 | 是的 | 是的 | 否 | 否 | 否 |
| 连接到另一个 SQL Server | 是的 | 是的 | 是的 | 否 | 否 | 否 |
| 连接到 Azure SQL 数据库或 Azure SQL 托管实例 | 是 3 | 是 3 | 是 3 | 否 | 否 | 否 |
| 连接到 Oracle/Teradata/MongoDB | 是的 | 是的 | 是的 | 否 | 否 | 否 |
| 连接到 Azure Blob 存储 | 是的 | 是的 | 是的 | 是的 | 是的 | 否 |
| 连接到 ADLS Gen2 | 是 5 | 是的 | 是的 | 是的 | 是的 | 否 |
| 连接到与 S3 兼容的存储 | 否 | 是的 | 是的 | 否 | 否 | 否 |
| 连接到OneLake(Fabric) | 否 | 否 | 否 | 否 | 否 | 是的 |
| 下推计算 | 是的 | 是的 | 是的 | 否 | 否 | 否 |
| 托管身份验证 | 否 | 否 | 是 4 | 是的 | 是的 | 否 |
1 SQL Server 2019 (15.x) 支持 OPENROWSET(BULK...) 本地和网络文件路径。 在 SQL Server 2022(16.x)及更高版本中,OPENROWSET(BULK...) 还支持使用FORMAT = 'PARQUET'、FORMAT = DELTA 和 FORMAT = 'CSV' 从云存储读取数据。
2 在 SQL Server 2019 (15.x)中,CSV 支持依赖于 Hadoop。 在 SQL Server 2022(16.x)及更高版本中,CSV 可以不依赖 Hadoop 而获得支持。
3 使用 SQL Server 连接器 (sqlserver://)。 数据库范围凭据面向 SQL 端点。 使用连接另一个 SQL Server 实例时相同的步骤。
4 连接到 Azure Blob 存储 (ABS) 和 ADLS Gen2 支持托管标识身份验证。 它需要为本地 SQL Server 使用启用 Azure Arc 的 SQL Server 或 Azure VM 上的 SQL Server。 它在 Azure SQL 数据库和 Azure SQL 托管实例上本地支持。
5 SQL Server 2019 CU11 及更高版本支持带有 abfs 或 abfss 前缀的 Azure Data Lake Storage Gen2。 在 SQL Server 2022 及更高版本中,使用 adls 前缀。
- SQL Server 2019、SQL Server 2022、SQL Server 2025、Azure SQL 数据库、Azure SQL 托管实例 以及 Microsoft Fabric 中的 SQL 数据库都支持外部表。
-
OPENROWSET (BULK)支持于 SQL Server 2019、SQL Server 2022、SQL Server 2025、Azure SQL 数据库、Azure SQL 托管实例 以及 Microsoft Fabric 中的 SQL 数据库。 SQL Server 2019 支持本地和网络文件路径,而 SQL Server 2022 及以后版本也支持读取云存储,包含FORMAT = 'PARQUET'、FORMAT = DELTA和FORMAT = 'CSV'。 - SQL Server 2019、Azure SQL 数据库 或 Microsoft Fabric 中的 SQL 数据库都不支持 CETAS 导出功能。 CETAS 导出支持于 SQL Server 2022、SQL Server 2025 和 Azure SQL 托管实例。
- SQL Server 2019、SQL Server 2022、SQL Server 2025、Azure SQL 数据库、Azure SQL 托管实例 以及 Microsoft Fabric 中的 SQL 数据库都支持 CSV 和分隔文件。 SQL Server 2019 需要 Hadoop 支持 CSV,而 SQL Server 2022 及以后版本则原生支持 CSV 而不支持 Hadoop。
- SQL Server 2019 不支持 Parquet 文件。 SQL Server 2022、SQL Server 2025、Azure SQL 数据库、Azure SQL 托管实例 和 Microsoft Fabric 中的 SQL 数据库均支持 Parquet 文件。
- SQL Server 2019、Azure SQL 数据库、Azure SQL 托管实例 或 Microsoft Fabric 中的 SQL 数据库不支持 Delta Lake 表。 SQL Server 2022 和 SQL Server 2025 支持三角湖表。
- 在 SQL Server 2019、SQL Server 2022 和 SQL Server 2025 中,支持连接到另一个 SQL Server 实例。 Azure SQL 数据库、Azure SQL 托管实例 或 Microsoft Fabric 中的 SQL 数据库都不支持连接到其他 SQL Server 实例。
- 从 SQL Server 2019、SQL Server 2022 和 SQL Server 2025 开始,支持使用 SQL Server 连接器连接到 Azure SQL 数据库或 Azure SQL 托管实例。 数据库范围的凭据针对的是 Azure SQL 数据库 或 Azure SQL 托管实例 端点,配置步骤与连接另一个 SQL Server 实例相同。 这些连接不支持来自 Azure SQL 数据库、Azure SQL 托管实例 或 Microsoft Fabric 中的 SQL 数据库。
- 自 SQL Server 2019、SQL Server 2022 和 SQL Server 2025 起,支持连接到 Oracle、Teradata 或 MongoDB。 这些连接不支持来自 Azure SQL 数据库、Azure SQL 托管实例 或 Microsoft Fabric 中的 SQL 数据库。
- SQL Server 2019、SQL Server 2022、SQL Server 2025、Azure SQL 数据库 和 Azure SQL 托管实例 支持连接到 Azure Blob 存储。 Microsoft Fabric 的 SQL 数据库不支持连接 Azure Blob 存储。
- 在 CU11 之前的 SQL Server 2019 版本中,也不支持从 Microsoft Fabric 中的 SQL 数据库连接 ADLS Gen2。 从 SQL Server 2019 CU11 开始,支持连接到 ADLS Gen2;SQL Server 2022、SQL Server 2025、Azure SQL 数据库 和 Azure SQL 托管实例 也支持此功能。
- SQL Server 2019、Azure SQL 数据库、Azure SQL 托管实例 或 Microsoft Fabric 中的 SQL 数据库都不支持连接兼容 S3 的存储。 从 SQL Server 2022 和 SQL Server 2025 起,支持连接兼容 S3 的存储。
- 支持通过 Microsoft Fabric 中的 SQL 数据库连接 OneLake。 SQL Server 2019、SQL Server 2022、SQL Server 2025、Azure SQL 数据库 或 Azure SQL 托管实例 不支持连接 OneLake。
- 推下计算在 SQL Server 2019、SQL Server 2022 和 SQL Server 2025 中得到支持。 Azure SQL 数据库、Azure SQL 托管实例 或 Microsoft Fabric 中的 SQL 数据库都不支持推下计算。
- SQL Server 2019 和 SQL Server 2022 不支持托管身份认证。 SQL Server 2025 支持管理身份认证,用于连接 Azure Blob 存储 和 ADLS Gen2,并且需要支持 Azure Arc 的 SQL Server 或 Azure 虚拟机上的 SQL Server。 Azure SQL 数据库 和 Azure SQL 托管实例 也支持托管身份认证,但在 Microsoft Fabric 的 SQL 数据库中不支持。
注释
从 SQL Server 2025(17.x)开始,查询 Azure Blob 存储、ADLS Gen2 或 S3 兼容的存储上的数据文件(CSV、Parquet 和 Delta)是本机引擎功能,不再需要安装或运行 PolyBase 服务。 RDBMS 连接器(SQL Server、Oracle、Teradata、MongoDB、ODBC)仍需要安装并运行 PolyBase 服务。 SQL Server 2025 (17.x) 还增加了对这些连接器的 Linux 支持,这些连接器以前仅在 Windows 上可用。
查询外部数据
在选择特定方案之前,请了解查询外部数据的三种方法:
| 方法 | Syntax | 何时使用 | 身份验证 | 需要安装 PolyBase |
|---|---|---|---|---|
| OLE DB 即席查询 | OPENROWSET(provider, connection, query) |
需要快速的一次性查询,而无需持久对象,或需要Microsoft Entra ID 身份验证 | SQL 身份验证、Windows 身份验证、Microsoft Entra ID (MSOLEDBSQL) | 否 |
| 文件上的临时查询 | OPENROWSET(BULK ...) |
在创建表之前,需要快速浏览文件数据或测试架构 | SAS 令牌、访问密钥、托管标识、Microsoft Entra ID | SQL Server 2022:是 1 SQL Server 2025及以后版本:否 Azure SQL 数据库、Azure SQL 托管实例 和 Fabric 中的 SQL 数据库:内置 |
| 持久数据连接器 |
CREATE EXTERNAL TABLE 与 sqlserver://、 oracle://、 teradata://等 |
需要重复访问、管理、统计和下推计算以进行生产 | 仅 SQL 身份验证 | 是的 |
1 在 SQL Server 2022(16.x)中访问云文件时,必须安装 PolyBase 功能,但支持 Azure Blob 存储、ADLS Gen2 和 S3 的存储连接器并不依赖于 PolyBase 服务。 SQL Server 2025(17.x)及更高版本原生支持 CSV、Parquet 和 Delta,无需安装或运行 PolyBase 服务。
- OLE DB 的临时查询用于
OPENROWSET(provider, connection, query)快速一次性访问远程数据源,而无需创建持久对象。 他们可以通过 MSOLEDBSQL 使用 SQL 身份验证、Windows 身份验证或 Microsoft Entra ID。 这种情况不需要安装PolyBase。 - 对文件
OPENROWSET(BULK ...)进行临时查询用于快速探索文件数据或测试模式,然后再创建表。 他们可以使用SAS令牌、访问密钥、托管身份(Managed Identity)或Microsoft Entra ID。 SQL Server 2022 要求云文件安装 PolyBase 功能,但不要求 PolyBase 服务。 SQL Server 2025及以后版本不需要为云文件提供PolyBase。 文件临时查询内置于 Azure SQL 数据库、Azure SQL 托管实例 和 Fabric 中的 SQL 数据库。 - 持久数据连接器使用
CREATE EXTERNAL TABLE以及sqlserver://、oracle://、teradata://等类似位置,以便在生产工作负载中实现重复访问、治理、统计信息收集和下推计算。 它们需要SQL认证和PolyBase服务。
决策指南
| 情景 | 建议 |
|---|---|
| 你需要 Microsoft Entra ID 认证来进行远程 SQL,或者想避免 PolyBase 服务。 | 使用 OPENROWSET(MSOLEDBSQL, ...)(临时,不会创建持久对象)。 |
| 你需要持久化表、统计信息,或者将计算下推到远程数据库。 | 使用 CREATE EXTERNAL TABLE 和 PolyBase 连接器(sqlserver://、oracle://、teradata://、mongodb://、odbc://)。
OPENROWSET 不支持连接器。 |
| 你是在探索一个新文件或测试一个模式。 | 使用 OPENROWSET(BULK ...) (快速迭代,无持久对象)。 |
| 你正在将文件数据导入表中,并进行转换。 | 使用 OPENROWSET(BULK ...) 中的 INSERT ... SELECT。 |
| 你需要治理或共享访问权限,适用于多个用户或应用。 | 请使用 CREATE EXTERNAL TABLE,以便集中管理权限和元数据。 |
| 你正在 Fabric 中使用 SQL 数据库。 | 即席 OneLake 查询使用 OPENROWSET(BULK ...),可重复使用的访问使用外部表;对于外部存储,使用 OneLake 快捷方式。 |
- 如果你需要对远程 SQL 使用 Microsoft Entra ID 身份验证,或者想要避免使用 PolyBase 服务,请使用
OPENROWSET(MSOLEDBSQL, ...)进行即席远程查询,而无需持久性对象。 - 如果你需要持久表、统计信息或向远程数据库下推计算,可以使用
CREATE EXTERNAL TABLE,并配合 PolyBase 连接器,例如sqlserver://、oracle://、teradata://、mongodb://和odbc://。OPENROWSET不支持这些连接器。 - 如果你在探索新文件或测试模式,建议使用
OPENROWSET(BULK ...)以实现快速迭代且无持久对象。 - 如果你是把文件数据导入带有变换的表,可以用
INSERT ... SELECTfromOPENROWSET(BULK ...). - 如果你需要为多用户或应用提供治理或共享访问权限,请使用
CREATE EXTERNAL TABLESO权限和元数据集中管理。 - 如果你在 Fabric 的 SQL 数据库中工作,可使用
OPENROWSET(BULK ...)对 OneLake 执行即席查询,或使用外部表实现可重复使用的访问;对于外部存储,请使用 OneLake 快捷方式。
选择场景
了解这三种方法后,请使用以下指南之一来实现特定的用例。
查询文件(Parquet、CSV 或 Delta)
如果数据位于 Azure Blob 存储、ADLS Gen2、S3 兼容的存储或 OneLake 上的 Parquet、CSV 或 Delta 文件中,请按照以下指南之一操作:
| 情景 | 推荐指南 | Platforms |
|---|---|---|
| 在 Parquet 或 CSV 文件上进行快速临时查询 | 使用 OPENROWSET。 不需要外部表 |
SQL Server 2022 (16.x) 及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Fabric 中的 SQL 数据库 |
| 对具有持久性架构的 Parquet 文件的重复查询 | 通过 Parquet 创建外部表 | SQL Server 2022 (16.x) 及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Fabric 中的 SQL 数据库 |
| 使用外部表查询 CSV 文件 | 使用带分隔符文本的文件格式创建外部表 | SQL Server 2019 (15.x) 及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Fabric 中的 SQL 数据库 |
| 查询 Delta Lake 表 | 使用 FILE_FORMAT = DeltaLakeFileFormat 创建外部表 |
SQL Server 2022 (16.x) 及更高版本 |
| 将查询结果导出 到 Parquet 或 CSV 文件(CETAS) | 使用 CREATE EXTERNAL TABLE AS SELECT |
SQL Server 2022 (16.x) 及更高版本 Azure SQL 托管实例 |
- 对于Parquet或CSV文件进行快速的临时查询,可以使用
OPENROWSET。 这种方法不需要外部表。 SQL Server 2022(16.x)及以后版本,如Azure SQL 数据库、Azure SQL 托管实例和Fabric中的SQL database Database都支持这种模式。 - 对于具有持久模式的 Parquet 文件的重复查询,可以使用外部表代替 Parquet。 SQL Server 2022(16.x)及以后版本,如Azure SQL 数据库、Azure SQL 托管实例和Fabric中的SQL database Database都支持这种模式。
- 对于CSV文件的查询,使用带有分隔文本文件格式的外部表格。 SQL Server 2019(15.x)及以后版本,Azure SQL 数据库、Azure SQL 托管实例 和 SQL database in Fabric 都支持这种模式。
- 对于对三角湖表的查询,使用带有
FILE_FORMAT = DeltaLakeFileFormat的外部表。 SQL Server 2022(16.x)及以后版本支持该模式。 - 如需将查询结果导出为Parquet或CSV文件,请使用
CREATE EXTERNAL TABLE AS SELECT。 SQL Server 2022(16.x)及以后版本和 Azure SQL 托管实例 支持这种模式。
还可以按照以下分步教程之一操作:
| 教程 | 说明 |
|---|---|
| SQL Server 2022 中的 PolyBase 入门 | 包含 Parquet 和 CSV、外部表和文件夹导航的 OPENROWSET。 |
| 使用 PolyBase 在 S3 兼容对象存储中虚拟化 parquet 文件 | SQL Server 2022(16.x)及更高版本的教程。 |
| 使用 PolyBase 虚拟化 CSV 文件 | SQL Server 2022(16.x)及更高版本的教程。 |
| 使用 PolyBase 虚拟化 Delta 表 | SQL Server 2022(16.x)及更高版本的教程。 |
| 使用 Azure SQL 数据库进行数据虚拟化(预览版) | 适用于 Parquet 和 CSV 的 Azure SQL 数据库指南。 |
| Azure SQL 托管实例的数据虚拟化 | 适用于 Parquet、CSV 和 CETAS 的 Azure SQL 托管实例指南。 |
| Fabric 中 SQL 数据库中的数据虚拟化 | Fabric 中 SQL 数据库的 OneLake 文件指南。 |
连接到另一个 SQL Server 实例、Azure SQL 数据库或 SQL 托管实例
在 SQL Server 2019(15.x)及更高版本中,PolyBase 可以在不使用链接服务器的情况下查询其他 SQL Server 实例、Azure SQL 数据库或 Azure SQL 托管实例中的表。
重要
Fabric 中的 SQL 数据库中不支持连接器 sqlserver:// 。 PolyBase RDBMS 连接器通过 CREATE DATABASE SCOPED CREDENTIAL 使用 SQL 身份验证,并且不支持 Microsoft Entra ID、托管标识或服务主体身份验证。 由于 Fabric 中的 SQL 数据库需要Microsoft Entra 身份验证,因此无法使用 PolyBase 连接到该数据库。
| 步骤 | 怎么办 |
|---|---|
| 1. 安装 PolyBase | 在 Windows 上安装 PolyBase 或在 Linux 上安装 PolyBase |
| 2.创建凭据 | 使用目标登录信息的 CREATE DATABASE SCOPED CREDENTIAL |
| 3.创建外部数据源 | CREATE EXTERNAL DATA SOURCE ... WITH (LOCATION = 'sqlserver://<server>') |
| 4.创建外部表 | CREATE EXTERNAL TABLE ... WITH (LOCATION = '<db>.<schema>.<table>') |
| 5. 查询 | SELECT * FROM <external_table> |
-
- 在配置对外部 SQL 数据的访问之前,使用 在 Windows 上安装 PolyBase 或 在 Linux 上安装 PolyBase,在 Windows 或 Linux 上安装 PolyBase。
-
- 使用
CREATE DATABASE SCOPED CREDENTIAL创建带有目标登录名的数据库范围凭据,以便引擎可以向远程服务器进行身份验证。
- 使用
-
- 使用
CREATE EXTERNAL DATA SOURCE ... WITH (LOCATION = 'sqlserver://<server>')为远程 SQL Server 创建外部数据源。
- 使用
-
- 通过用
CREATE EXTERNAL TABLE ... WITH (LOCATION = '<db>.<schema>.<table>')来表示远程表,创建一个外部表。
- 通过用
-
- 通过使用
SELECT * FROM <external_table>查询外部表。
- 通过使用
小窍门
SQL Server 连接器 (sqlserver://) 也适用于 Azure SQL 数据库和 Azure SQL 托管实例。 使用相同的步骤,并将 LOCATION 设置为 Azure SQL 数据库 或 Azure SQL 托管实例 的终结点(例如 sqlserver://myserver.database.windows.net)。
有关详细指南,请参阅 配置 PolyBase 以访问 SQL Server 中的外部数据。
连接到 Oracle、Teradata 或 MongoDB
SQL Server 2019 (15.x) 及更高版本可以通过 PolyBase ODBC 连接器查询 Oracle、Teradata、MongoDB 和 Cosmos DB。
| 数据源 | 指南 | 要求 |
|---|---|---|
| Oracle | 配置 PolyBase 以访问 Oracle 中的外部数据 | SQL Server 2019 (15.x) 及更高版本、Oracle 客户端驱动程序 |
| Teradata | 配置 PolyBase 以访问 Teradata 中的外部数据 | SQL Server 2019 (15.x) 及更高版本 Teradata ODBC 驱动程序 |
| MongoDB /Cosmos DB | 配置 PolyBase 以访问 MongoDB 中的外部数据 | SQL Server 2019 (15.x) 及更高版本 MongoDB ODBC 驱动程序 |
| 任何 ODBC 数据源 | 配置 PolyBase 以使用 ODBC 泛型类型访问外部数据 | SQL Server 2019 (15.x) 及更高版本 (Windows) (从 SQL Server 2025 (17.x) 开始的 Linux) |
- Oracle 数据源使用 Configure PolyBase 访问 Oracle 指南中的外部数据,并需要 SQL Server 2019(15.x)及更高版本和 Oracle 客户端驱动。
- Teradata 数据源使用 Configure PolyBase 访问 Teradata 指南中的外部数据,需要 SQL Server 2019(15.x)及更高版本和 Teradata ODBC 驱动。
- MongoDB 或 Cosmos DB 数据源使用配置 PolyBase 访问 MongoDB 外部数据指南,并需要 SQL Server 2019(15.x)及以后版本和 MongoDB ODBC 驱动。
- 任何 ODBC 源都可以使用 Configure PolyBase 访问外部数据,并附有 ODBC 通用类型指南,并且需要在 Windows 上使用 SQL Server 2019(15.x)及以后版本,在 Linux 上则需要 SQL Server 2025(17.x)及以后版本。
连接到 Azure Blob 存储或 ADLS Gen2
| SQL 平台 | 身份验证选项 | 指南 |
|---|---|---|
| SQL Server 2022 (16.x) 及更高版本 | SAS 令牌、访问密钥、托管标识(从 SQL Server 2025(17.x)开始) | 配置 PolyBase 以访问 Azure Blob 存储中的外部数据 |
| SQL Server 2019 (15.x) | 访问密钥(通过 Hadoop 连接器) | 配置 PolyBase 以访问 Azure Blob 存储中的外部数据 |
| Azure SQL 数据库 | SAS 令牌、托管标识、Microsoft Entra 直通 | 使用 Azure SQL 数据库进行数据虚拟化(预览版) |
| Azure SQL 托管实例 | SAS 令牌,托管标识 | Azure SQL 托管实例的数据虚拟化 |
- SQL Server 2022 及以后版本从 2025 SQL Server(17.x)起支持通过 SAS 令牌、访问密钥或托管身份(Managed Identity)进行 Azure Blob 存储 或 ADLS Gen2 认证。 有关详细信息,请参阅 配置 PolyBase 以访问 Azure Blob 存储中的外部数据。
- SQL Server 2019 通过 Hadoop 连接器使用访问密钥支持 Azure Blob 存储 或 ADLS Gen2。 有关详细信息,请参阅 配置 PolyBase 以访问 Azure Blob 存储中的外部数据。
- Azure SQL 数据库 通过使用 SAS 令牌、管理身份认证或 Microsoft Entra 直通认证支持 Azure Blob 存储 或 ADLS Gen2。 有关详细信息,请参阅 Azure SQL 数据库的数据虚拟化(预览版)。
- Azure SQL 托管实例 通过使用 SAS 令牌或托管身份支持Azure Blob 存储 或 ADLS Gen2。 有关详细信息,请参阅 Azure SQL 托管实例的数据虚拟化。
在 SQL Server 2022(16.x)中,URI 前缀已更改。 从 SQL Server 2019(15.x)或早期版本迁移时:
-
Azure Blob 存储:将
wasb[s]://更改为abs:// -
ADLS Gen2:将
abfs[s]://更改为adls://
有关详细信息,请参阅 配置 PolyBase 以访问 Azure Blob 存储中的外部数据。
连接到与 S3 兼容的对象存储
SQL Server 2022 (16.x) 及更高版本支持 S3 兼容的存储,例如 Amazon S3、MinIO 和 Ceph。
有关详细信息,请参阅配置 PolyBase 以访问 S3 兼容的对象存储中的外部数据。
使用 CREATE EXTERNAL TABLE AS SELECT (CETAS) 导出数据
CETAS 将查询结果导出到 Azure Blob 存储、ADLS Gen2 或 S3 兼容的存储中的外部文件(Parquet 或 CSV)。
| SQL 平台 | 支持 | 导出格式 | 备注 |
|---|---|---|---|
| SQL Server 2022(16.x)及以后版本。 使用 CETAS 导出到 ADLS Gen2 需要 SQL Server 2022 CU5 或更高版本。 | 是的 | Parquet、CSV | 需要 服务器配置:允许导出多基底。 |
| Azure SQL 托管实例 | 是的 | Parquet、CSV | 默认禁用 |
| Azure SQL 数据库 | 否 | 没有 | 不可用 |
| Fabric 中的 SQL 数据库 | 否 | 没有 | 不可用 |
- SQL Server 2022及以后版本支持CETAS,并支持导出Parquet和CSV文件。 服务器配置:允许 PolyBase 导出 设置是必需的。 在 SQL Server 2022 的 CU5 之前版本中,不支持将 CETAS 导出到 ADLS Gen2。
- Azure SQL 托管实例 支持 CETAS,并导出 Parquet 和 CSV 文件。 默认禁用指南描述了其默认状态。
- Azure SQL 数据库不支持 CETAS。
- Fabric 中的 SQL 数据库不支持 CETAS。
有关 Transact-SQL 参考,请参阅 CREATE EXTERNAL TABLE AS SELECT (CETAS)。
快速入门示例
示例 1:对 Parquet 文件的临时查询 (OPENROWSET)
不需要外部表。 适用于 Fabric 中的 SQL Server 2022(16.x)及更高版本、Azure SQL 数据库、Azure SQL 托管实例和 SQL 数据库。
SELECT TOP 10 *
FROM OPENROWSET (
BULK 'abs://mycontainer@mystorageaccount.blob.core.windows.net/data/sales/*.parquet',
FORMAT = 'PARQUET'
) AS [result];
示例 2:Azure Blob 存储中基于 CSV 的外部表
这个例子适用于所有支持通过CSV文件传输外部表的SQL平台。
步骤 1:创建数据库主密钥(DMK)。 此步骤是必需的,因为凭据存储 SAS 令牌机密。 不过,如果你使用托管身份认证或 Microsoft Entra 认证,可以跳过这一步。
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>';步骤 2:使用 SAS 令牌创建凭据。 省略前导
?。CREATE DATABASE SCOPED CREDENTIAL MyStorageCred WITH IDENTITY = 'SHARED ACCESS SIGNATURE', SECRET = '<your_SAS_token>'; -- omit the leading '?'步骤 3:创建外部数据源。
CREATE EXTERNAL DATA SOURCE MyAzureStorage WITH ( LOCATION = 'abs://mycontainer@mystorageaccount.blob.core.windows.net', CREDENTIAL = MyStorageCred );步骤 4:为 CSV 创建文件格式。
CREATE EXTERNAL FILE FORMAT CsvFormat WITH ( FORMAT_TYPE = DELIMITEDTEXT, FORMAT_OPTIONS ( FIELD_TERMINATOR = ',', STRING_DELIMITER = '"', FIRST_ROW = 2 ) );步骤 5:创建外部表。
CREATE EXTERNAL TABLE dbo.SalesExternal ( OrderId INT, OrderDate DATE, Amount DECIMAL (18, 2), Customer NVARCHAR (100) ) WITH ( DATA_SOURCE = MyAzureStorage, LOCATION = '/data/sales/', FILE_FORMAT = CsvFormat );步骤 6:查询外部表。
SELECT * FROM dbo.SalesExternal WHERE OrderDate >= '2025-01-01';
示例 3:查询另一个 SQL Server 中的表
此示例适用于 SQL Server 2019(15.x)及更高版本。
步骤 1:创建数据库主密钥(由于凭据存储密码而必需)。
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>';步骤 2:为远程 SQL Server 实例创建凭据。
CREATE DATABASE SCOPED CREDENTIAL RemoteSqlCred WITH IDENTITY = 'remote_user', SECRET = '<password>';步骤 3:创建外部数据源。
CREATE EXTERNAL DATA SOURCE RemoteSqlServer WITH ( LOCATION = 'sqlserver://remote-server.contoso.com', PUSHDOWN = ON, CREDENTIAL = RemoteSqlCred );步骤 4:创建外部表(由三部分构成的名称)。
LOCATIONCREATE EXTERNAL TABLE dbo.RemoteCustomers ( CustomerId INT, CustomerName NVARCHAR (200) COLLATE SQL_Latin1_General_CP1_CI_AS ) WITH ( DATA_SOURCE = RemoteSqlServer, LOCATION = 'SalesDB.dbo.Customers' );步骤 5:跨服务器查询。
SELECT c.CustomerName, s.Amount FROM dbo.RemoteCustomers AS c INNER JOIN dbo.LocalSales AS s ON c.CustomerId = s.CustomerId;
示例 4:使用 CETAS 将结果导出到 Parquet
适用于 SQL Server 2022(16.x)及更高版本 Azure SQL 托管实例。
步骤 1:启用 CETAS(仅限 SQL Server)。
EXECUTE sp_configure 'allow polybase export', 1; RECONFIGURE;步骤 2:创建凭据和数据源(从前面的示例中重复使用)。
步骤 3:为 Parquet 导出创建文件格式。
CREATE EXTERNAL FILE FORMAT ParquetFormat WITH ( FORMAT_TYPE = PARQUET );步骤 4:导出查询结果。
CREATE EXTERNAL TABLE dbo.Sales2025Export WITH ( DATA_SOURCE = MyAzureStorage, LOCATION = '/exports/sales_2025.parquet', FILE_FORMAT = ParquetFormat ) AS SELECT * FROM Sales.Orders WHERE OrderDate >= '2025-01-01';
PolyBase 的 T-SQL 构建基块
在实现任何方案之前,请了解 PolyBase 使用的核心 T-SQL 对象及其组合方式:
展示 PolyBase T-SQL 对象及其关系的示意图,从身份验证(数据库主密钥、凭据),经由数据源和文件格式,到查询方法(外部表、OPENROWSET、BULK INSERT、CETAS)。
- 关于外部数据源语法,请参见 CREATE EXTERNAL DATA SOURCE。
- 关于外部文件格式语法,请参见 CREATE EXTERNAL FILE FORMAT。
- 关于外部表语法,请参见 CREATE EXTERNAL TABLE。
- 关于临时数据访问语法,请参见 OPENROWSET。
- 关于CETAS语法,请参见CREATE EXTERNAL TABLE AS SELECT(CETAS)。
有关所有对象的完整 Transact-SQL 引用,请参阅 PolyBase Transact-SQL 参考。
重要
检查外部文件格式的数据类型映射。 使用 PolyBase 创建外部文件格式或查询文件时 OPENROWSET,会自动将源数据类型(Parquet、CSV、Delta、Oracle、Teradata、MongoDB)映射到 SQL Server 数据类型。 不匹配的类型可能会导致无提示截断、精度丢失或查询错误。 例如,Parquet DECIMAL(38,18) 映射到 DECIMAL(18,0). 在定义外部表列或 WITH 子句之前,请查看映射表。 有关完整参考,请参阅 PolyBase 的类型映射。
你什么时候需要 CREATE MASTER KEY?
数据库主密钥(DMK)是使用 CREATE MASTER KEY 语法创建的。 DMK 对数据库范围凭据中存储的机密进行加密。 仅当凭据包含机密值(即存储密码、令牌或访问密钥时)时才需要它。
DMK 是必需的 (凭据存储机密):
身份验证类型 IDENTITY值有秘密 DMK SAS 令牌 'SHARED ACCESS SIGNATURE'是的 必需 S3 访问密钥 'S3 ACCESS KEY'是的 必需 SQL 登录名/基本身份验证 '<username>'是的 必需 存储帐户访问密钥 '<storage_account_name>'是的 必需 - SAS令牌凭证使用
IDENTITY = 'SHARED ACCESS SIGNATURE'并存储一个秘密值,因此需要数据库主密钥。 - S3访问密钥凭证使用
IDENTITY = 'S3 ACCESS KEY'并存储一个秘密值,因此需要数据库主密钥。- SQL 登录或基本认证凭证使用
IDENTITY = '<username>'并存储一个秘密值,因此需要数据库主密钥。
- SQL 登录或基本认证凭证使用
- 存储账户访问密钥凭证使用
IDENTITY = '<storage_account_name>'并存储一个秘密值,因此需要数据库主密钥。
- SAS令牌凭证使用
DMK 不是必需的 (没有存储机密):
身份验证类型 IDENTITY值有秘密 DMK 托管的标识 'Managed Identity'否 不是必需 Microsoft Entra ID 'User Identity'或'Managed Identity'否 不是必需 - 托管身份凭证不使用
IDENTITY = 'Managed Identity'和存储任何秘密信息,因此不需要数据库主密钥。 - Microsoft Entra ID 凭证不使用
IDENTITY = 'User Identity'或IDENTITY = 'Managed Identity'存储任何秘密,因此不需要数据库主密钥。
- 托管身份凭证不使用
小窍门
如果你 CREATE DATABASE SCOPED CREDENTIAL 的声明里没有秘密信息,你就不需要DMK。 托管身份和Microsoft Entra ID身份验证将信任委托给平台。 数据库不存储密码或令牌。
示例:
在此示例查询中,DMK 是必需的(凭据存储 SAS 令牌)。
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>';
CREATE DATABASE SCOPED CREDENTIAL SasCred
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = '<your_SAS_token>';
在此示例查询中,数据库主密钥 (DMK) 不是必需的(托管身份,无需使用秘密)。
CREATE DATABASE SCOPED CREDENTIAL ManagedIdentityCred
WITH IDENTITY = 'Managed Identity';
在此示例查询中,DMK 不是必需的(Microsoft Entra pass-through,无秘密)。
CREATE DATABASE SCOPED CREDENTIAL EntraIdCred
WITH IDENTITY = 'User Identity';
使用 OPENROWSET 和外部表进行远程数据访问
SQL Server 提供了三种不同的方法来查询远程数据。 了解语法、身份验证和体系结构的差异时,可以选择正确的方法。
| 方法 | Syntax | 连接到 | 身份验证 | PolyBase 服务 | Platforms |
|---|---|---|---|---|---|
| OLE DB 查询 | OPENROWSET(provider, connection, query) |
通过 MSOLEDBSQL、SQLOLEDB 或其他提供程序使用的任何 OLE DB 源 | SQL 身份验证、Windows 身份验证、Microsoft Entra ID (MSOLEDBSQL) | 否 | SQL Server (所有受支持的版本) |
| SQL Server 2022(16.x)和SQL Server 2019(15.x)中的文件查询 | OPENROWSET(BULK ...) |
本地磁盘、网络或云上的文件(Azure Blob、ADLS、S3、OneLake) | SAS 令牌、访问密钥、托管标识、Microsoft Entra ID | 云端 1 为是;本地为否 | SQL Server 2022 (16.x) 和 SQL Server 2019 (15.x) |
| SQL Server 2025(17.x)及后续版本中的文件查询 | OPENROWSET(BULK ...) |
本地磁盘、网络或云上的文件(Azure Blob、ADLS、S3、OneLake) | SAS 令牌、访问密钥、托管标识、Microsoft Entra ID | 否 | SQL Server 2022 (16.x) 及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Fabric 中的 SQL 数据库 |
| PolyBase 连接器 |
CREATE EXTERNAL TABLE 与使用 CREATE EXTERNAL DATA SOURCE、sqlserver://、oracle://、teradata://、mongodb:// 的 odbc:// |
远程 SQL Server、Oracle、Teradata、MongoDB、ODBC 源 | 仅 SQL 身份验证 | 是的 | SQL Server 2019 (15.x) 及更高版本 (Windows):SQL Server 2025 (17.x) 及更高版本 (Linux) |
1 在 SQL Server 2022(16.x)中访问云文件,必须安装 PolyBase 功能。
- OLE DB 查询在所有受支持的 SQL Server 版本中,都可使用
OPENROWSET(provider, connection, query)通过 MSOLEDBSQL、SQLOLEDB 或其他提供程序连接到任意 OLE DB 源。 它们支持 SQL 身份验证、Windows 身份验证,以及通过 MSOLEDBSQL 使用 Microsoft Entra ID,并且不需要安装 PolyBase 服务。 - 文件查询用于
OPENROWSET(BULK ...)读取本地磁盘、网络共享或云存储(如 Azure Blob 存储、ADLS、S3 或 OneLake)上的文件,方法包括 SAS 令牌、访问密钥、管理身份或 Microsoft Entra ID。 它们支持SQL Server 2005及以后版本的本地和网络文件,SQL Server 2022(16.x)及以后版本的云文件,以及Azure SQL 数据库、Azure SQL 托管实例和Fabric中的SQL数据库。 在 SQL Server 2022(16.x)及以后版本中,本地文件或云文件查询不需要 PolyBase 服务。 - PolyBase 连接器使用
CREATE EXTERNAL TABLE和CREATE EXTERNAL DATA SOURCE,并借助oracle://、sqlserver://、teradata://、mongodb://或odbc://位置连接到远程 SQL Server、Oracle、Teradata、MongoDB 或 ODBC 源。 它们要求在SQL Server 2019(15.x)及以后版本(Windows)和SQL Server 2025(17.x)及以后版本中支持SQL认证和PolyBase服务。 有关详细信息,请参阅CREATE EXTERNAL DATA SOURCE(Transact-SQL)。
何时使用每个方法
将 OLE DB OPENROWSET 用于:
- 使用 OLE DB
OPENROWSET进行快速的一次性临时查询,无需创建持久对象。 - 使用OLE DB
OPENROWSET进行Microsoft Entra ID或MSOLEDBSQL托管身份认证。 - 使用OLE DB
OPENROWSET以避免PolyBase服务依赖。 - 使用 OLE DB
OPENROWSET连接任何带有 OLE DB 提供者的数据源。
将 文件 OPENROWSET(BULK) 用于:
- 使用文件
OPENROWSET(BULK ...)进行临时文件探索和模式发现。 - 在提交表定义前,使用文件
OPENROWSET(BULK ...)进行快速变换和预览。 - 使用
OPENROWSET(BULK ...)文件进行灵活的内联列转换,例如类型转换、筛选和计算列。 - 使用
OPENROWSET(BULK ...)文件处理不频繁变化且不需要持久元数据的数据。
将 PolyBase 连接器与 CREATE EXTERNAL TABLE 配合使用,用于:
- 将 PolyBase 连接器与
CREATE EXTERNAL TABLE配合使用,以创建供多个用户或应用程序访问的持久且可重用的表定义。 - 对需要统计信息和查询计划优化的生产工作负载,请将 PolyBase 连接器与
CREATE EXTERNAL TABLE结合使用。 - 将 PolyBase 连接器与
CREATE EXTERNAL TABLE配合使用,以便将计算下推到 Oracle 和 SQL Server 等远程数据源。 - 将 PolyBase 连接器与
CREATE EXTERNAL TABLE配合使用,以实现共享治理和安全性;创建表后,用户只需具备SELECT权限。 - 当可以对远程源使用 SQL 身份验证时,请将 PolyBase 连接器与
CREATE EXTERNAL TABLE一起使用。
OPENROWSET (OLE DB) - 临时远程查询(不需要 PolyBase 服务)
OPENROWSET 的 OLE DB 形式通过 OLE DB 提供程序连接到远程数据源,执行透传查询,并将结果作为数据行集返回。 它是链接服务器的一次性临时替代方法。 不会创建持久性元数据。 此语法不需要 PolyBase 服务,也不支持云文件或外部数据源。
此示例查询通过 OLE DB(而不是 PolyBase)连接到远程 SQL Server。
SELECT *
FROM OPENROWSET (
'MSOLEDBSQL',
'Server=remote-server;Database=AdventureWorks;Trusted_Connection=yes;',
'SELECT TOP 10 * FROM AdventureWorks.Sales.SalesOrderHeader'
);
OPENROWSET(BULK) - 基于文件的查询(PolyBase)
BULK 的 OPENROWSET 形式直接从文件读取数据。 在 SQL Server 2019(15.x)和早期版本中,它从本地或 UNC 文件路径读取,并需要格式化文件。 在 SQL Server 2022(16.x)及更高版本中,可以使用和DATA_SOURCE参数从FORMAT中读取数据。 此方法是用于数据虚拟化的 PolyBase 集成版本。
在 PolyBase 和数据虚拟化背景下,本指南中提到OPENROWSET时,是指使用OPENROWSET(BULK ...)语法,并通过FORMAT子句来查询外部文件。
示例:
此示例查询从 Azure Blob 存储(SQL Server 2022 及更高版本)读取 Parquet 文件。
SELECT TOP 10 *
FROM OPENROWSET (
BULK 'data/sales/*.parquet',
DATA_SOURCE = 'MyAzureStorage',
FORMAT = 'PARQUET'
) AS [result];
此示例查询使用内联路径(Azure SQL 数据库、Azure SQL 托管实例)读取 Parquet 文件。
SELECT TOP 10 *
FROM OPENROWSET (
BULK 'abs://mycontainer@mystorageaccount.blob.core.windows.net/data/sales/*.parquet',
FORMAT = 'PARQUET'
) AS [result];
何时使用 OPENROWSET 与外部表
和 OPENROWSET(BULK ...) 外部表都允许使用 T-SQL 查询外部数据,但它们专为不同的用例而设计。 下表总结了有助于确定哪种方法适合你的方案的关键差异。
| 能力 | OPENROWSET(BULK ...) |
外部表 |
|---|---|---|
| Purpose | 即席探索和一次性查询 | 持久、可重用的表定义 |
| 存储在数据库中的元数据 | 否。 查询运行后不会保存任何内容 | 是的。 表定义、数据源和文件格式存储为数据库对象 |
| 架构定义 | 从文件 (Parquet) 自动推断或使用 WITH 子句内联指定 |
显式地在语句 CREATE EXTERNAL TABLE 中定义 |
| 权限 | 需要 ADMINISTER BULK OPERATIONS 或 ADMINISTER DATABASE BULK OPERATIONS |
创建后,对表的标准 SELECT 权限就足够了 |
| 计算列 | 是的。 在 SELECT 列表中添加表达式和计算列;元数据函数(如 filename() 和 filepath() 此处仅可用)。 |
否。 固定列列表;在读取外部表的视图或查询中执行转换 |
| 统计 | Azure SQL 托管实例:使用sys.sp_create_openrowset_statistics手动创建单列统计信息。 请参阅 OPENROWSET 手动统计信息。 SQL Server 2022 (16.x) 及以后版本,Azure SQL 数据库、Fabric 中的 SQL 数据库:自动创建谓词统计。 SQL Server不支持手动 OPENROWSET统计。 |
在所有平台上提供全面 CREATE STATISTICS 支持,同时在 SQL Server 2022(16.x)及更高版本中实现自动创建。 请参阅 「创建外部表手动统计信息」。 |
| 下推 | 有限的支持。 引擎可能会将筛选器下推到文件扫描,但不支持下推到远程 RDBMS 源 | 是的。 支持 RDBMS 连接器的下推计算(SQL Server、Oracle、Teradata、MongoDB) |
| 最适用于 | 数据探索、架构发现、原型查询、一次性数据加载、灵活转换 | 生产工作负荷、重复查询、跨用户、仪表板和报告共享访问权限 |
-
OPENROWSET(BULK ...)最适合临时探索和一次性查询,而外部表则更适合持久且可复用的表定义。 -
OPENROWSET(BULK ...)查询运行后不将元数据存储在数据库中,而外部表则以数据库对象的形式存储表定义、数据源和文件格式。 -
OPENROWSET(BULK ...)会从 Parquet 文件中自动推断架构,或通过WITH子句内联定义架构,而外部表则会在CREATE EXTERNAL TABLE语句中显式定义架构。 -
OPENROWSET(BULK ...)需要ADMINISTER BULK OPERATIONS或ADMINISTER DATABASE BULK OPERATIONS,而外部表在创建后,可由仅具有标准SELECT权限的用户查询。 -
OPENROWSET(BULK ...)支持查询和元数据函数中的计算列,如filename()和filepath(),而外部表则有固定的列列表,需要在视图或读取外部表的查询中进行变换。 -
OPENROWSET(BULK ...)统计支持有限:Azure SQL 托管实例 可以用于sys.sp_create_openrowset_statistics单列统计,但 SQL Server 2022(16.x)及以后版本、Azure SQL 数据库 和 Fabric 中的 SQL 数据库会自动创建谓词统计数据。 SQL Server、Azure SQL 数据库 和 Fabric 中的 SQL 数据库都不支持手动OPENROWSET统计。 外部表支持所有平台的完整CREATE STATISTICS功能,并在 SQL Server 2022(16.x)及以后版本、Azure SQL 数据库 和 Fabric 中的 SQL 数据库中自动统计。 参见 OPENROWSET 手动统计信息和创建外部表手动统计信息。 -
OPENROWSET(BULK ...)的下推能力有限,且无法向远程 RDBMS 源下推,而外部表支持针对 RDBMS 连接器的计算下推。 -
OPENROWSET(BULK ...)它最适合数据探索、模式发现、原型设计、一次性加载和灵活转换,而外部表则最适合生产工作负载、重复查询、共享访问、仪表盘和报告。
需要灵活性时使用 OPENROWSET
用于 OPENROWSET 浏览文件、测试不同的架构或添加计算列和转换,而无需创建任何持久性对象。 例如,可以将文件路径提取为列、内联强制转换数据类型,或筛选单个查询中的计算表达式。
此示例查询包括计算列和转换:
SELECT result.filename() AS [FileName],
result.filepath(1) AS [Year],
result.filepath(2) AS [Month],
CAST (OrderDate AS DATE) AS OrderDate,
Amount,
OrderDate
FROM OPENROWSET (
BULK 'abs://mycontainer@mystorageaccount.blob.core.windows.net/data/sales/*/*/*/*.parquet',
FORMAT = 'PARQUET'
) AS result
WHERE result.filepath(1) = '2025';
小窍门
Azure SQL 数据库、Azure SQL 托管实例和 SQL Server 2022(16.x)及更高版本中提供了这些 filepath() 和 filename() 函数。 它们允许您过滤文件路径的各个部分(分区消除),并将源文件名称作为一列公开,而这在外部表中是无法直接做到的。
需要持久性和治理时使用外部表
当多个用户或应用程序需要重复查询相同的外部数据时,请使用外部表。 定义架构、数据源和凭据一次,并将其存储在数据库中。 使用者只需 SELECT 对表具有权限。
外部表还支持 统计信息,查询优化器使用该统计信息来生成更好的执行计划。 可以手动创建统计信息,或者让引擎自动创建统计信息(SQL Server 2022 (16.x) 及更高版本)。
此示例查询为更好的查询计划创建外部表的统计信息。
CREATE STATISTICS Stats_OrderDate
ON dbo.SalesExternal(OrderDate)
WITH FULLSCAN;
有关这两种方法的统计信息的详细信息,请参阅 PolyBase 性能注意事项 - 统计信息。
BULK INSERT 与 OPENROWSET(BULK):我应该使用哪一个?
两个BULK INSERT和OPENROWSET(BULK ...)都使用相同的基础大容量加载引擎将数据从文件导入到SQL Server。 但是,它们在语法、灵活性和可以对结果执行的操作方面有所不同。 下表对主要差异进行了汇总:
注释
BULK INSERT独立语句在 Fabric 的 SQL 数据库中不被支持。 要导入数据,请使用 INSERT ... SELECT 结合 OPENROWSET(BULK ...) 针对 OneLake。
| 能力 | BULK INSERT |
OPENROWSET(BULK ...) |
|---|---|---|
| 基本用途 | 将数据直接从文件加载到 目标表中 | 返回您在 或 SELECT 语句中使用的INSERT ... SELECT |
| 使用模式 | 独立语句: BULK INSERT <table> FROM '<file>' |
必须在查询中使用: SELECT * FROM OPENROWSET(BULK ...)INSERT INTO <table> SELECT * FROM OPENROWSET(BULK ...) |
| 需要目标表? | 是的。 始终直接写入表 | 否。 您可以从它 SELECT,而无需插入到任何位置,或插入到任何表或临时表中。 |
| 加载期间的列转换 | 有限的支持。 数据原样从文件流向表(映射由格式文件或列顺序控制) | 完全支持。 您可以在周围的 CAST 中添加表达式、WHERE、JOIN 筛选器、SELECT 其他表和计算列 |
| 表格提示 | 该WITH子句包括对BATCHSIZE、CHECK_CONSTRAINTS、FIRE_TRIGGERS、KEEPIDENTITY、KEEPNULLS、TABLOCK等内容的支持,以及更多。 |
支持通过 INSERT ... SELECT * FROM OPENROWSET(BULK ...) WITH (TABLOCK, IGNORE_CONSTRAINTS, ...) 语法来提供表提示 |
| 大型对象 (LOB) 单值导入 | 不支持 | 是的。 支持SINGLE_BLOB、SINGLE_CLOB、SINGLE_NCLOB将整个文件导入为一个 varbinary(max)、 varchar(max)或 nvarchar(max)值 |
| 格式化文件 | 是的。 支持通过 (XML 和非 XML) | 是的。 支持 (XML 和非 XML) |
| 云文件访问 |
DATA_SOURCE 在 SQL Server 2017(14.x)及更高版本、Azure SQL 数据库 和 Azure SQL 托管实例 中支持 Azure Blob 存储。 SQL Server 2019 CU11及以后版本也支持 ADLS Gen2。 不支持兼容S3的存储。 |
DATA_SOURCE支持SQL Server 2017(14.x)及更高版本中的Azure Blob 存储,SQL Server 2019 CU11及更高版本支持ADLS Gen2,并在SQL Server 2022(16.x)及更高版本中支持S3兼容存储。 Azure SQL 数据库 和 Azure SQL 托管实例 支持 Azure Blob 存储 和 ADLS Gen2. Fabric 中的 SQL 数据库支持 OneLake 和通过 OneLake 快捷方式的外部存储。 |
| Parquet 或 Delta 文件 | 不支持。 仅限于 CSV/分隔符文本 | 是的。 SQL Server 2022(16.x)及更高版本、Azure SQL 托管实例 和 Azure SQL 数据库 支持 FORMAT = 'PARQUET' 和 FORMAT = 'DELTA';Fabric 中的 SQL 数据库支持 FORMAT = 'PARQUET',但不支持 DELTA。 有关详细信息,请参阅 OPENROWSET BULK (Transact-SQL)。 |
| 所需权限 |
ADMINISTER BULK OPERATIONS或者ADMINISTER DATABASE BULK OPERATIONS,在目标表上加INSERT |
ADMINISTER BULK OPERATIONS 或 ADMINISTER DATABASE BULK OPERATIONS |
| 最小日志记录 | 是的。 在使用 TABLOCK 的简单或大容量日志恢复模式下受支持 |
是的。 在与 INSERT ... SELECT 和 TABLOCK 一起使用时受支持 |
-
BULK INSERT直接将数据从文件加载到目标表中,而OPENROWSET(BULK ...)返回一个可在INSERT ... SELECT或SELECT语句中使用的行集。 -
BULK INSERT是独立语句,而OPENROWSET(BULK ...)必须在查询中使用,如SELECT * FROM OPENROWSET(BULK ...)或INSERT INTO <table> SELECT * FROM OPENROWSET(BULK ...)。 -
BULK INSERT始终直接写入目标表,而OPENROWSET(BULK ...)可以从文件中SELECT而不插入任何位置,也可以插入到任何表或临时表中。 -
BULK INSERT对列转换的支持有限,因为数据从文件到表是按原样流动的,而映射由格式文件或列顺序控制。OPENROWSET(BULK ...)支持表达式、CAST、JOIN过滤器、SELECT以及周围的WHERE中的计算列。 -
BULK INSERT使用WITH子句用于BATCHSIZE、CHECK_CONSTRAINTS、FIRE_TRIGGERS、TABLOCK、KEEPNULLS、KEEPIDENTITY及其他提示。OPENROWSET(BULK ...)通过INSERT ... SELECT * FROM OPENROWSET(BULK ...) WITH (TABLOCK, IGNORE_CONSTRAINTS, ...)支持表提示。 -
BULK INSERT不支持大对象单值导入。OPENROWSET(BULK ...)支持SINGLE_BLOB、SINGLE_CLOB和SINGLE_NCLOB,分别将整个文件导入为单个 varbinary(max)、varchar(max) 或 nvarchar(max) 值。 - 两者都
BULK INSERTOPENROWSET(BULK ...)支持 XML 和非 XML 格式文件。 - 对于使用
DATA_SOURCE的云文件访问,BULK INSERT参数在 SQL Server 2017 (14.x) 及更高版本、Azure SQL 数据库 和 Azure SQL 托管实例 中支持 Azure Blob 存储。 SQL Server 2019 CU11及以后版本也支持 ADLS Gen2,但BULK INSERT不支持 S3 兼容存储。 对于OPENROWSET(BULK ...),DATA_SOURCE支持SQL Server 2017(14.x)及以后版本中的Azure Blob 存储,在SQL Server 2019 CU11及以后版本中支持ADLS Gen2,在SQL Server 2022(16.x)及以后版本中支持S3兼容的存储。 Azure SQL 数据库 和 Azure SQL 托管实例 支持 Azure Blob 存储 和 ADLS Gen2. Fabric 中的 SQL 数据库支持 OneLake 和通过 OneLake 快捷方式的外部存储。 -
BULK INSERT不支持 Parquet 或 Delta 文件,只支持 CSV 或分隔文本。OPENROWSET(BULK ...)支持 SQL Server 2022(16.x)及更高版本、Azure SQL 数据库 和 Azure SQL 托管实例 中的FORMAT = 'PARQUET'和FORMAT = 'DELTA'。 Fabric 中的 SQL 数据库支持FORMAT = 'DELTA',但不支持FORMAT = 'PARQUET'。 有关详细信息,请参阅 OPENROWSET BULK (Transact-SQL)。 -
BULK INSERT需要ADMINISTER BULK OPERATIONS或ADMINISTER DATABASE BULK OPERATIONS加INSERT目标表上的许可,而OPENROWSET(BULK ...)要求ADMINISTER BULK OPERATIONS或ADMINISTER DATABASE BULK OPERATIONS。 -
BULK INSERT在简单恢复模式或大容量日志恢复模式下,配合TABLOCK支持最小日志记录。OPENROWSET(BULK ...)在与INSERT ... SELECT和TABLOCK一起使用时,支持最小的日志记录。
何时选择 BULK INSERT
当您需要进行简单的文件到表加载时,并且在导入过程中不需要转换、筛选或联接数据,请使用BULK INSERT。 它对 CSV 或其他带分隔符的文件使用更简单的语法:
此示例查询将 CSV 文件直接从 Azure Blob 存储加载到表中。
BULK INSERT Sales.Invoices
FROM 'invoices/inv-2025-01.csv'
WITH (
DATA_SOURCE = 'MyAzureBlobStorage',
FORMAT = 'CSV',
FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
);
此示例查询加载本地文件,并使用格式文件进行列映射。
BULK INSERT dbo.Products
FROM 'C:\Data\products.csv'
WITH (
FORMATFILE = 'C:\Data\products.fmt',
FIRSTROW = 2,
TABLOCK
);
何时选择 OPENROWSET(BULK)
需要以下一个或多个条件时使用 OPENROWSET(BULK ...) :
- 用于
OPENROWSET(BULK ...)查询或预览文件数据,无需先创建表。 - 导入时用于
OPENROWSET(BULK ...)转换、过滤或连接数据。 - 用
OPENROWSET(BULK ...)来加载Parquet或Delta文件,因为它们BULK INSERT不支持这些格式。 - 使用
OPENROWSET(BULK ...)可将整个文件作为单个 LOB 值导入,配合SINGLE_BLOB、SINGLE_CLOB或SINGLE_NCLOB。
此示例查询从 Azure Blob 存储预览 CSV 文件,而无需在任意位置插入数据。
SELECT TOP 10 *
FROM OPENROWSET (
BULK 'invoices/inv-2025-01.csv',
DATA_SOURCE = 'MyAzureBlobStorage',
FORMAT = 'CSV',
FIRSTROW = 2,
FIELDTERMINATOR = ','
) AS src;
此示例查询使用转换和筛选插入数据。
INSERT INTO Sales.Invoices (InvoiceDate, Amount, Customer)
SELECT CAST (InvoiceDate AS DATE),
Amount * 1.1, -- Apply a 10% markup
UPPER(Customer)
FROM OPENROWSET (
BULK 'invoices/inv-2025-01.csv',
DATA_SOURCE = 'MyAzureBlobStorage',
FORMAT = 'CSV',
FIRSTROW = 2
) WITH (
InvoiceDate VARCHAR (10),
Amount DECIMAL (18, 2),
Customer VARCHAR (100)
) AS src
WHERE Amount IS NOT NULL;
此示例查询加载 Parquet 文件(不能使用BULK INSERT)。
INSERT INTO Sales.Invoices
SELECT *
FROM OPENROWSET (
BULK 'data/invoices/*.parquet',
DATA_SOURCE = 'MyAzureStorage',
FORMAT = 'PARQUET') AS src;
此示例查询将整个 XML 文件导入为单个 varbinary(max) 值。
INSERT INTO dbo.XmlDocuments (DocContent)
SELECT BulkColumn
FROM OPENROWSET (
BULK 'C:\Data\catalog.xml',
SINGLE_BLOB
) AS x;
小窍门
一种方法是首先使用 OPENROWSET(BULK ...) 中的 SELECT 探索和验证文件数据,如果不需要转换,然后切换到 BULK INSERT 进行最终生产负载。 如果需要 Parquet 或 Delta 支持或内联筛选,继续使用 OPENROWSET。
有关详细信息,请参阅以下相关指南:
- 《使用 BULK INSERT 或 OPENROWSET(BULK...) 将数据导入 SQL Server》 一文提供了包含安全注意事项的详细对照指南。
- 《大批量数据导入和导出(SQL Server)》文章概述了所有大批量数据移动方法,包括 bcp 和
BULK INSERTOPENROWSET。 -
BULK INSERT (Transact-SQL)文章提供了完整的
BULK INSERTT-SQL参考文献。 -
OPENROWSET BULK (Transact-SQL) 一文提供了有关
OPENROWSET(BULK ...)的完整 T-SQL 参考。 - 《Azure Blob 存储 中数据批量访问示例》一文并列展示了两种方法与 Azure 存储 的并排示例。
- 《使用 OPENROWSET 大容量行集提供程序批量导入大对象数据(SQL Server)》一文提供了
SINGLE_BLOB、SINGLE_CLOB和SINGLE_NCLOB示例。 -
《使用格式文件批量导入数据(SQL Server)》文章解释了两种格式文件的使用方法。
- 关于在批量导入时保留空值或应用默认值的指导,请参见“在批量导入时保留空值或默认值(SQL Server)”。
- 关于在批量导入时保留身份值的指导,请参见“批量导入数据时保持身份值(SQL Server)”。
有用的元数据函数
当你通过外部 OPENROWSET 表查询外部文件时,可以使用内置的功能和过程来检查文件元数据、发现模式,并实现分区感知查询。
filepath() 和 filename()
filepath() 和 filename() 函数返回结果集中每一行的文件路径或文件名的一部分。 它们特别适用于:
分区消除:筛选文件夹段(例如年/月/日分区),以便引擎仅读取匹配的文件,而不是扫描所有内容。
公开源元数据:将原始文件名或路径作为列包含在查询结果中,这有助于审核或调试。
| 功能 | 退货 | 示例 |
|---|---|---|
filename() |
每个行的源文件的文件名(包括扩展名) | sales_2025_01.parquet |
filepath(N) |
路径中通配符 (*) 中的第 BULK 个文件夹段,N 从 1 开始 |
对于路径 sales/2025/01/*.parquet, filepath(1) 返回 2025, filepath(2) 返回 01 |
适用于:Azure SQL 数据库、Azure SQL 托管实例、SQL Server 2022(16.x)及更高版本(Fabric 中的 SQL 数据库)。
此示例查询用于 filepath() 分区消除和 filename() 标识源文件。 它只读取文件夹下 /2025/ 的文件,并且仅读取子文件夹下 /06/ 的文件。
SELECT result.filename() AS SourceFile,
result.filepath(1) AS [Year],
result.filepath(2) AS [Month],
*
FROM OPENROWSET (
BULK 'abs://mycontainer@mystorageaccount.blob.core.windows.net/data/sales/*/*/*.parquet',
FORMAT = 'PARQUET'
) AS result
WHERE result.filepath(1) = '2025'
AND result.filepath(2) = '06';
小窍门
将filepath()筛选器放在WHERE子句中,而不是放在子查询或 CTE 中。 当筛选器位于 WHERE 子句中时,查询引擎可以在文件扫描级别进行分区消除,从而大大减少输入/输出操作。
sp_describe_first_result_set - 发现 OPENROWSET 列类型
与 Parquet 文件一起使用 OPENROWSET 时,引擎会自动推断列数据类型(架构推理)。 推断的类型可能大于所需。 例如,字符列通常被推断为 varchar(8000), 因为 Parquet 元数据不包含最大长度。 此选项可能会降低性能并消耗更多内存。
使用 sp_describe_first_result_set 在最终确定查询之前检查推断的架构。 看到推断的类型后,请在子句中 WITH 指定更窄的类型以提高性能。
步骤 1:检查推断的架构。
EXECUTE sp_describe_first_result_set N' SELECT * FROM OPENROWSET( BULK ''abs://mycontainer@mystorageaccount.blob.core.windows.net/data/sales/*.parquet'', FORMAT = ''PARQUET'' ) AS result';输出显示每个列的名称、推断的数据类型、最大长度、精度和小数位。 如果你看到 varchar(8000),而 varchar(100) 就足够了,那就把它改掉。
步骤 2:使用显式类型来提高性能。
SELECT TOP 100 * FROM OPENROWSET ( BULK 'abs://mycontainer@mystorageaccount.blob.core.windows.net/data/sales/*.parquet', FORMAT = 'PARQUET' ) WITH ( OrderId INT, OrderDate DATE, Amount DECIMAL (18, 2), Customer VARCHAR (100) -- much narrower than the inferred varchar(8000) ) AS result;
模式推断仅适用于 Parquet 文件。 对于 CSV 文件,始终在 WITH 子句(用于 OPENROWSET)或 CREATE EXTERNAL TABLE 语句中指定列定义。
sp_describe_first_result_set 是一个适用于 SQL Server、Azure SQL 数据库、Azure SQL 托管实例 以及 Fabric 中 SQL 数据库的通用过程,但它对于 OPENROWSET 查询尤其有用。 有关更多信息,请参阅 sp_describe_first_result_set。
性能、故障排除和最佳做法
实现数据虚拟化后,请使用以下指南优化性能、诊断问题并确保生产就绪性:
| 面积 | 文章 | 详细信息 |
|---|---|---|
| PolyBase 性能 | SQL Server 的 PolyBase 中的性能注意事项 | 统计信息、下推、并行度和内存管理 |
| 下推计算 | PolyBase 中的下推计算 | 指定哪些操作推送到远程源 |
| 如何判断是否发生了下推 | 如何判断是否发生了外推 | 查询计划和 DMV |
| 故障排除 | 监视 PolyBase 并对其进行故障排除 | 常见错误和解决方案 |
| Kerberos 连接 | PolyBase Kerberos 连接故障排除 | |
| 常见问题 | PolyBase 常见问题解答 | |
| 错误和解决方案 | PolyBase 错误和可能的解决方案 |