本页面介绍并提供了各个 Spanner 查询优化器版本的历史记录。当前的默认版本为 6。 要详细了解查询优化器,请参阅查询优化器简介。
Spanner 将查询优化器更新作为新的查询优化器版本发布。默认情况下,每个数据库会在最新版本的优化工具发布后至少 30 天内开始使用该版本。
如果您使用的是 GoogleSQL 方言数据库,可以管理您的查询使用的查询优化器版本。在提交到最新版本之前,您可以比较旧版本和最新版本之间的查询性能配置文件。如需了解详情,请参阅管理查询优化器。
查询优化器版本记录
下面总结了在每个版本中对查询优化器进行的更新。
版本 7:2024 年 5 月 22 日(最新)
添加了对基于费用选择索引联合方案的支持。
针对所有关键部分都没有可查找谓词的查询,添加了对根据统计信息智能选择还原计划与扫描计划的支持。
添加了对基于费用选择哈希联接的支持。
版本 6:2023 年 9 月 11 日(默认)
改进了通过全外联接的限制推送和谓词推送。
改进了基数估算和费用模型。
为 DML 查询启用了基于费用的优化。
版本 5:2022 年 7 月 15 日
改进了索引选择、分布管理、对展示位置进行排序和
GROUP BY
选择的费用模型。添加了对基于费用的联接算法选择的支持,可在哈希和应用联接之间进行选择。合并联接仍需要使用查询提示。
添加了对基于费用的联接交换的支持。
版本 4:2022 年 3 月 1 日
改进了二级索引选择。
- 改进了交错表之间的联接下的二级索引使用情况。
- 改进了对二级索引用法的覆盖。
- 改进了优化器统计信息过时时的索引选择。
- 即使优化器统计信息不可用或报告基表较小,也首选用在前导索引列上添加谓词的二级索引。
引入了单遍哈希联接,由新提示
hash_join_execution
启用。联接提示:
GoogleSQL
SELECT ... FROM (...) JOIN@{join_method=hash_join, hash_join_execution=one_pass} (...)
PostgreSQL
SELECT ... FROM (...) JOIN/*@ join_method=hash_join, hash_join_execution=one_pass */ (...)
当哈希连接的构建辅助输入很大时,新模式非常有用。如果您在查询执行配置文件中观察到以下情况,一遍哈希联接预计会带来更好的性能:
- 哈希联接的右侧子项上的执行数量大于哈希联接运算符上的执行数量。
- 哈希联接运算符的右侧子级的延迟时间也较长。
默认情况下 (
hash_join_execution=multi_pass
),如果哈希联接的构建端输入太大而无法放入内存,构建端会拆分为多个批次,并且我们可能会多次扫描探测端。使用新模式 (hash_join_execution=one_pass
) 时,如果内存的构建端输入无法容纳,哈希联接将溢出到磁盘,并且始终只对探测端扫描一次。改进了选择用于跳转的键的数量。
版本 3:2021 年 8 月 1 日
添加了一种新的联接算法——合并联接(通过使用新的 JOIN METHOD 查询提示值来启用)。
语句提示:
GoogleSQL
@{join_method=merge_join} SELECT ...
PostgreSQL
/*@ join_method=merge_join */ SELECT ...
加入提示:
GoogleSQL
SELECT ... FROM (...) JOIN@{join_method=merge_join} (...)
PostgreSQL
SELECT ... FROM (...) JOIN/*@ join_method=merge_join */ (...)
添加了一种新的联接算法——推送广播哈希联接(通过使用新的 JOIN METHOD 查询提示值来启用)。
加入提示:
GoogleSQL
SELECT ... FROM (...) JOIN@{join_method=push_broadcast_hash_join} (...)
PostgreSQL
SELECT ... FROM (...) JOIN/*@ join_method=push_broadcast_hash_join} */ (...)
引入了分布式合并联合运算符,该运算符在适用时默认启用。此操作可提高查询性能。
当 SELECT 列表中没有 MAX 或 MIN 汇总(或 HAVING MAX/MAX)时,
GROUP BY
下的扫描性能略有提升。在此次更改之前,Spanner 加载了这个额外的非分组列,即使查询不需要该列也是如此。例如,请参考下表:
GoogleSQL
CREATE TABLE myTable( a INT64, b INT64, c INT64, d INT64) PRIMARY KEY (a, b, c);
PostgreSQL
CREATE TABLE myTable( a bigint, b bigint, c bigint, d bigint, PRIMARY KEY(a, b, c) );
在此更改之前,以下查询将加载
c
列,即使查询不需要该列也不例外。SELECT a, b FROM myTable GROUP BY a, b
当联接引入交叉应用运算符,并且查询要求按 LIMIT 排序结果时,使用
LIMIT
改进了某些查询的性能。此更改之后,优化器会先在交叉应用的输入端应用排序限制。示例:
GoogleSQL
SELECT a2.* FROM Albums@{FORCE_INDEX=_BASE_TABLE} a1 JOIN Albums@{FORCE_INDEX=_BASE_TABLE} a2 USING(SingerId) ORDER BY a1.AlbumId LIMIT 2;
PostgreSQL
SELECT a2.* FROM albums/*@ force_index=_base_table */ a1 JOIN albums/*@ force_index=_base_table */ a2 USING(singerid) ORDER BY a1.albumid LIMIT 2;
通过
JOIN
推送更多计算来改进查询性能。推送更多计算,其中可能包括通过联接进行的子查询或结构体构造。这样可以通过几种方式提高查询性能,例如:可以通过分布式方式执行更多计算,也可以下推更多依赖于推送计算的操作。例如,如果查询存在限制,并且排序顺序取决于这些计算,那么也可以通过联接推送此限制。
示例:
SELECT t.ConcertDate, ( SELECT COUNT(*) FROM UNNEST(t.TicketPrices) p WHERE p > 10 ) AS expensive_tickets, u.VenueName FROM Concerts t JOIN Venues u ON t.VenueId = u.VenueId ORDER BY expensive_tickets LIMIT 2;
版本 2:2020 年 3 月 1 日
- 在索引选择中添加优化。
- 提高了
REGEXP_CONTAINS
和LIKE
谓词在某些情况下的性能。 - 改进了某些情况下
GROUP BY
下的扫描性能。
版本 1:2019 年 6 月 18 日
包括许多基于规则的优化,例如谓词下推、限制下推、冗余联接和冗余表达式移除等。
使用用户数据统计信息来选择用于访问每个表的索引。