借助 SQL 分析终结点,可以使用 T-SQL 语言和 TDS 协议查询 Lakehouse 中的数据。 它利用了Fabric Data Warehouse引擎。
小窍门
有关优化 Delta 表用于 SQL 分析终结点使用的全面跨工作负载指南,包括文件大小建议和行组建议,请参阅 跨工作负载表维护和优化。
每个湖屋都有一个 SQL 分析端点。 工作区中的 SQL 分析端点数与在该工作区中预配的湖屋和镜像数据库数匹配。
后台进程负责扫描 lakehouse 中的更改,并使 SQL 分析终结点针对工作区中各个 lakehouse 里提交的所有更改保持最新。 Fabric 平台透明地管理同步过程。 当在湖屋中检测到更改时,后台进程会更新元数据,SQL 分析端点会反映提交给湖屋表的更改。 在正常操作条件下,湖屋和 SQL 分析端点之间的滞后时间不到一分钟。 根据本文讨论的许多因素,实际时间长度可能从几秒钟到分钟不等。 后台进程在SQL分析端点处于激活状态时运行,15分钟后停止,且没有查询活动。
Guidance
- 自动元数据发现跟踪提交给 Lakehouse 的更改,并且在每个 Fabric 工作区中是一个单独的实例。 如果您发现湖屋与 SQL 分析终结点之间的更改同步延迟增加,这可能是因为单个工作区中存在大量湖屋。 在这种情况下,请考虑将每个湖仓迁移到单独的工作区,这样可使自动元数据发现实现扩展。
- Parquet 文件本质上是不可变的。 当发生更新或删除操作时,Delta 表会添加包含变更集的新 Parquet 文件。随着时间推移,文件数量会增加,具体取决于更新和删除操作的频率。 如果不计划维护,此模式最终将产生读取开销,此条件会影响将更改同步到 SQL 分析终结点所需的时间。 若要解决此问题,请定期安排湖仓表维护作业。
- 在某些情况下,你可能会发现,提交到 Lakehouse 的更改在关联的 SQL 分析终结点中不可见。 例如,可以在 Lakehouse 中创建新表,但尚未在 SQL 分析终结点中列出。 或者,你可能已向 Lakehouse 中的表提交了大量行数据,但这些数据在 SQL 分析终结点中暂时还不可见。 你可以在 Fabric 门户中启动按需元数据同步,或使用 Refresh SQL 分析端点元数据 REST API。
- 自动同步过程不支持所有 Delta 功能。 有关 Fabric 中每个引擎支持的功能的详细信息,请参阅 Delta Lake 表格式互作性。
- 如果在提取转换和加载 (ETL) 处理期间存在非常大的表更改,则在处理所有更改之前会发生预期的延迟。
优化 Lakehouse 表以查询 SQL 分析终结点
当 SQL 分析终结点读取存储在 Lakehouse 中的表时,查询性能在很大程度上取决于基础 Parquet 文件的物理布局。 该引擎在 Parquet 文件级别对扫描进行并行处理。 过多的小文件会增加文件和元数据开销,而过少的大文件会限制扫描并行性。
对于 Spark 编写的表格,请使用Fabric Spark 2.0或更高版本的默认设置。 这些运行时默认支持 自适应目标文件大小 ,以选择最优的表目标文件大小,从小表的128 MB到最大表的1 GB。 避免在默认配置基础上设置静态目标或任意的行数限制。 行数限制未考虑行宽,因此对于较窄的表,可能会生成较小的文件。
如果你使用Fabric Spark 1.3运行时,请启用自适应目标文件大小和文件级压缩目标,这些功能作为选择加入功能提供。
V-Order主要有利于Power BI Direct Lake,虽然它能提升某些工作负载的压缩率,但通常默认情况下并非最佳SQL分析端点性能的必需或推荐。
默认写入设置不能替代表维护。 请遵循以下做法,以在表格发生变化时保持布局正常:
- 对于周期性增加的同步写入延迟可接受的工作负载,启用 自动压缩 功能。 自动压缩是Spark的一个功能,只有在表格中小文件过多时才会运行。
- 对于自动压实带来的额外周期性延迟无法满足数据更新 SLA 要求的工作负载,请安排周期性
OPTIMIZE作业。 - 根据保留和时间回溯要求运行
VACUUM,以删除 Delta 日志不再引用的文件。VACUUM虽然减少了保留的存储空间,但并不能改善活跃文件的布局。 - 避免高基数分区和会导致生成大量小文件的自定义写入器配置。
如果不使用自动压缩,请在运行 OPTIMIZE 之前,使用数据管道和 sys.sp_get_table_health_metrics T-SQL 存储过程来识别需要维护的表。 有关本教程,请参阅 根据运行状况检查优化 Lakehouse 表。
注释
有关 Lakehouse 表常规维护的指导,请参阅 Lakehouse 的运行表维护。
分区大小注意事项
分区布局会影响SQL分析端发现和同步变化所需的时间。 大量分区或较小的Parquet文件会增加元数据扫描的开销。 遵循以下做法:
- 避免使用高基数的分区列,因为这可能会为每个唯一值创建一个分区。 选择一个列,使其生成的分区接近或大于 1 GB。 更多信息请参见 三角洲湖表分区。
- 批处理和流式引入在变更频繁或变更幅度较小时,可能会生成小文件。 使用定期的Lakehouse 表维护来压缩整理这些文件。
要评估每个分区的大小和文件数量,可以使用 示例脚本来获取分区细节。
分区详细信息的示例脚本
使用以下笔记本打印一份报告,详细说明Delta表下层分区的大小和细节。
- 首先,在变量
delta_table_path中为你的 Delta 表提供 ABFSS 路径。- 可以通过 Fabric 门户的资源管理器获取增量表的 ABFSS 路径。 右键单击表名,然后从选项列表中选择
COPY PATH。
- 可以通过 Fabric 门户的资源管理器获取增量表的 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']}")