本文提供如何提高 Lakehouse 联合查询性能的指导。
使用 AND
运算符合并多个谓词
Databricks Runtime 尝试将谓词向下推送到远程数据库引擎,以减少通过网络提取的记录数。 如果无法向下推送谓词,则对远程数据库引擎执行的查询将排除该谓词,因此必须使用 Databricks Runtime 执行筛选。 但是,如果无法向下推送筛选器的某些部分,则如果 AND 运算符联接筛选器的另一部分,仍可向下推送筛选器。
示例 1:
Databricks 查询
SELECT * FROM foreign_catalog.schema.table WHERE name ILIKE 'john'
ILIKE
无法将表达式向下推送到远程数据库(例如 MySQL),因为没有适当的翻译。
必须使用 Databricks Runtime 完成筛选。
发送到远程数据库的查询将返回所有记录:
SELECT * FROM catalog.schema.table
示例 2:
Databricks 查询
SELECT * FROM foreign_catalog.schema.table WHERE name ILIKE 'john' AND date > '2025-05-01'
ILIKE
表达式无法向下推送到远程数据库(例如 MySQL),因为不存在适当的转换,但日期比较是可以实现的。
名称筛选仍必须使用 Databricks Runtime 完成,但日期比较应减少正在提取的记录数。
发送到远程数据库的查询将返回记录的子集:
SELECT * FROM catalog.schema.table WHERE date > '2025-05-01'
检查应在远程数据库上执行的查询
可以使用 EXPLAIN FORMATTED 命令检查要发送到远程数据库的查询。
重要
由于 自适应查询执行,实际查询可能与解释命令输出中的查询不同。
设置从远程数据库提取的批大小
可以将使用 JDBC 传输协议的连接器配置为控制它们如何从远程系统提取数据:
- Databricks
- Microsoft SQL Server
- Azure Synapse
- MySQL
- Oracle
- PostgreSQL
- Redshift
- Salesforce 数据云
- Teradata
JDBC 提取大小确定每个往返提取的行数。 默认情况下,大多数 JDBC 连接器以原子方式提取数据。 这可能会导致数据量超过可用内存。
若要避免内存不足错误,请设置 fetchSize
参数。 当设置为非零值时 fetchSize
,连接器会分批读取数据。 每个批处理的最大行数等于值 fetchSize
。 Databricks 建议指定一 fetchSize
个大值(例如 100,000
),因为如果批中的行数太小,则可以延长整个查询执行时间。
此参数允许工作器节点分批读取数据,但不能并行读取数据。
计算要求:
- 必须在 Databricks Runtime 16.1 或更高版本上使用计算。 SQL 仓库必须是 Pro,并且必须使用 2024.50。
SELECT * FROM mySqlCatalog.schema.table WITH ('fetchSize' 100000)
设置分区大小参数 (Snowflake)
Snowflake 允许提取多个分区中的数据,从而能够参与多个执行器和并行处理。
必须通过设置 partition_size_in_mb
参数来选择适当的分区大小。
此参数指定每个分区的建议未压缩大小。 若要减少分区数,请指定更大的值。
默认值为 100
(MB)。
参数 partition_size_in_mb
设置建议的大小;分区的实际大小可能会有所不同。
计算要求:
- 必须在 Databricks Runtime 16.1 或更高版本上使用计算。 SQL 仓库必须是 Pro,并且必须使用 2024.50。
SELECT * FROM snowflakeCatalog.schema.table WITH ('partition_size_in_mb' 1000)
为 JDBC 连接器启用并行读取
支持 JDBC 传输协议的连接器可以通过对查询进行分区来并行读取数据。 可以为以下连接器配置并行读取:
- Databricks
- Microsoft SQL Server
- Azure Synapse
- MySQL
- Oracle
- PostgreSQL
- Redshift
- Salesforce 数据云
- Teradata
这允许多个执行程序同时提取数据,从而显著提高大型表的性能。
若要启用并行读取,请指定以下参数:
-
numPartitions
:要用于并行的分区数 -
partitionColumn
:用于对查询进行分区的数字列的名称 -
lowerBound
:用于确定分区步幅的partitionColumn
最小值 -
upperBound
:用于决定分区步幅的partitionColumn
最大值
重要
和lowerBound
upperBound
值仅用于决定分区步幅,而不是用于筛选表中的行。 将分区并返回表中的所有行。
分区列应为:
- 数字列
- 均匀分布于范围
- 索引列以提高性能
计算要求:
- 必须在 Databricks Runtime 17.1 或更高版本上使用计算。 SQL 仓库必须是专业或无服务器,并且必须使用 2025.25。
在以下示例中,查询将基于 id
列拆分为 4 个并行分区,每个分区处理一个大约 250 个 ID 的范围(假设每个 id
1
1000
ID 之间都有一条记录)。
SELECT * FROM mySqlCatalog.schema.table WITH (
'numPartitions' 4,
'partitionColumn' 'id',
'lowerBound' 1,
'upperBound' 1000
)