从Azure Synapse无服务器SQL池批量加载数据到Azure存储或Databricks Spark的最佳方法
元数据查询获取外部表底层存储位置
直接在Synapse无服务器SQL池的查询编辑器中执行以下SQL,替换对应的schema和表名参数,即可获得底层存储路径:
SELECT t.name AS external_table_name, s.name AS schema_name, ds.location AS underlying_storage_path, f.name AS file_format_name FROM sys.external_tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id INNER JOIN sys.external_data_sources ds ON t.data_source_id = ds.data_source_id INNER JOIN sys.external_file_formats f ON t.file_format_id = f.file_format_id WHERE s.name = '<你的表所属Schema,默认dbo>' AND t.name = '<已知的外部表名称>'
返回结果中的underlying_storage_path字段即为该外部表关联的Azure存储根路径。
批量加载最佳方案
按你提出的两个目标场景,分别对应以下最优实现方式:
场景1:直接加载到Databricks Spark
优先推荐直接读取底层存储文件,性能远高于走JDBC调用Synapse查询,仅在小数据量、需要复用Synapse的行级权限/复杂视图逻辑时再选择JDBC方式。
直接读底层文件(推荐)
- 先通过上述元数据查询拿到存储路径和文件格式
- 在Databricks中完成对应Azure存储的身份认证(支持存储账户密钥、SAS令牌、服务主体、ABFSS直接认证等方式)
- 直接读取路径下的文件即可,PySpark示例:
# 以Parquet格式为例,其他格式调整format参数和对应读取配置即可 df = spark.read.format("parquet").load("<查询得到的underlying_storage_path>")
JDBC加载方式
仅适合小数据量场景,PySpark示例:
synapse_jdbc_url = "jdbc:sqlserver://<Synapse工作区名>-ondemand.sql.azuresynapse.net:1433;database=<数据库名称>;user=<用户名>;password=<密码>;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.sql.azuresynapse.net;loginTimeout=30;" df = spark.read.format("jdbc") \ .option("url", synapse_jdbc_url) \ .option("dbtable", "<Schema名>.<外部表名>") \ .load()
场景2:批量导出到Azure存储
直接使用Synapse无服务器SQL池的CETAS语法完成导出,无需额外计算资源,全量批量导出效率最高,示例SQL:
-- 1. 创建导出目标的外部数据源 CREATE EXTERNAL DATA SOURCE ExportTargetDS WITH ( LOCATION = '<目标Azure存储的根路径,比如abfss://容器名@存储账户名.dfs.core.windows.net/导出目录>' ); -- 2. 创建导出用的文件格式 CREATE EXTERNAL FILE FORMAT ExportParquetFormat WITH ( FORMAT_TYPE = PARQUET, DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec' ); -- 3. 执行CETAS导出 CREATE EXTERNAL TABLE Exported_External_Table WITH ( LOCATION = 'partition_subpath/', -- 导出文件在目标路径下的子目录 DATA_SOURCE = ExportTargetDS, FILE_FORMAT = ExportParquetFormat ) AS SELECT * FROM <你的源外部表名>
内容的提问来源于stack exchange,提问作者Madhur Gupta
相关产品推荐
相关产品推荐

