Spanner 查询优化器确定执行 SQL 查询的最有效方式。但是,在查询优化器本身改进或更新数据库统计信息时,由优化器确定的查询计划可能会略有变化。为了在查询优化器或统计信息发生更改时最大限度地降低性能下降的可能性,Spanner 提供了以下查询选项。
optimizer_version:对查询优化器的更改捆绑并作为优化器版本发布。在最新版本的优化工具发布后至少 30 天内,Spanner 会默认开始使用最新版本的优化工具。您可以使用查询优化器版本选项对旧版优化器运行查询。
optimizer_statistics_package:Spanner 会定期更新优化器统计信息。新统计信息以软件包的形式提供。 此查询选项指定在编译 SQL 查询时查询优化器要使用的统计信息包。指定的软件包必须停用垃圾回收:
GoogleSQL
ALTER STATISTICSSET OPTIONS (allow_gc=false)
PostgreSQL
ALTER STATISTICS spanner."" SET OPTIONS (allow_gc = true)
本指南介绍如何在 Spanner 中的不同范围内设置这些单独的选项。
列出查询优化器选项
Spanner 会存储有关您可以选择的可用优化器版本和统计信息软件包的信息。
优化器版本
查询优化器版本是一个整数值,每次更新时递增 1。查询优化器的最新版本为 7。
执行以下 SQL 语句以返回所有受支持的优化器版本的列表及其相应的发布日期,以及该版本是否为默认版本。返回的最大版本号是支持的优化器最新版本。
SELECT * FROM SPANNER_SYS.SUPPORTED_OPTIMIZER_VERSIONS;
默认版本
默认情况下,Spanner 会在最新版本的优化工具发布后至少 30 天内开始使用该版本。从新版本到默认版本为期 30 天的宽限期内,建议您根据新版本测试查询,以检测是否有任何回归问题。
如需查找默认版本,请执行以下 SQL 语句:
SELECT * FROM SPANNER_SYS.SUPPORTED_OPTIMIZER_VERSIONS;
查询将返回所有受支持的优化器版本的列表。IS_DEFAULT
列指定的是当前默认版本。
如需详细了解每个版本,请参阅查询优化器版本版本记录。
优化器统计信息包
Spanner 创建的每个新的优化器统计信息软件包都分配有一个软件包名称,该名称保证在给定数据库中是唯一的。
软件包名称的格式为 auto_{PACKAGE_TIMESTAMP}UTC
。在 GoogleSQL 中,ANALYZE
语句会触发统计信息软件包名称的创建。在 PostgreSQL 中,ANALYZE
语句执行此任务。统计信息软件包名称的格式为 analyze_{PACKAGE_TIMESTAMP}UTC
,其中 {PACKAGE_TIMESTAMP}
是统计信息构建开始时的时间戳(采用世界协调时间 (UTC) 时区)。执行以下 SQL 语句,以返回所有可用优化器统计信息包的列表。
SELECT * FROM INFORMATION_SCHEMA.SPANNER_STATISTICS;
默认情况下,Spanner 会使用最新的优化器统计信息软件包,除非使用本页介绍的方法之一将数据库或查询固定到较旧的软件包。
选项替换优先级
如果您使用的是 GoogleSQL 方言数据库,Spanner 提供了多种更改优化器选项的方法。例如,您可以为特定查询设置选项,或者在进程或查询级别在客户端库中配置选项。如果通过多种方式设置某个选项,请遵循以下优先顺序。(选择链接即可跳转到本文档中的相应部分)。
Spanner 默认 ← 数据库选项 ← 客户端应用 ← 环境变量 客户端查询 ← 语句提示
例如,下面展示了如何在设置查询优化器版本时解释优先顺序:
创建数据库时,它会使用 Spanner 默认优化器版本。使用上面列出的方法之一设置优化器版本优先于其左侧的任何内容。例如,使用环境变量为应用设置优化器,优先于使用数据库选项为数据库设置的任何值。对于给定的查询,通过语句提示设置优化器版本具有最高优先级,其优先级高于使用任何其他方法设置的值。
现在,让我们来更详细地了解每种方法。
在数据库级别设置优化器选项
您可以使用以下 ALTER DATABASE
DDL 命令在数据库上设置默认优化器版本。
GoogleSQL
ALTER DATABASE MyDatabase
SET OPTIONS (optimizer_version = 7);
PostgreSQL
ALTER DATABASE MyDatabase SET spanner.optimizer_version = 5;
您可以以类似方式设置统计信息软件包,如以下示例所示。
GoogleSQL
ALTER DATABASE MyDatabase
SET OPTIONS (optimizer_statistics_package = "auto_20191128_14_47_22UTC");
PostgreSQL
ALTER DATABASE MyDatabase
SET spanner.optimizer_statistics_package = "auto_20191128_14_47_22UTC";
您还可以同时设置多个选项,如以下 DDL 命令所示。
GoogleSQL
ALTER DATABASE MyDatabase
SET OPTIONS (optimizer_version = 7,
optimizer_statistics_package = "auto_20191128_14_47_22UTC");
您可以在 gcloud CLI 中使用 gcloud CLI databases ddl update
命令运行 ALTER DATABASE
,如下所示。
GoogleSQL
gcloud spanner databases ddl update MyDatabase --instance=test-instance \
--ddl='ALTER DATABASE MyDatabase SET OPTIONS ( optimizer_version = 7 )'
PostgreSQL
gcloud spanner databases ddl update MyDatabase --instance=test-instance \
--ddl='ALTER DATABASE MyDatabase SET spanner.optimizer_version = 7'
将数据库选项设置为 NULL
(在 GoogleSQL 中)或 DEFAULT
(在 PostgreSQL 中)会清除该选项,以使用默认值。
如需查看数据库这些选项的当前值,请查询 INFORMATION_SCHEMA.DATABASE_OPTIONS
视图(对于 GoogleSQL)或 information_schema database_options
表(对于 PostgreSQL),如下所示。
GoogleSQL
SELECT
s.OPTION_NAME,
s.OPTION_VALUE
FROM
INFORMATION_SCHEMA.DATABASE_OPTIONS s
WHERE
s.SCHEMA_NAME=""
AND s.OPTION_NAME IN ('optimizer_version', 'optimizer_statistics_package')
PostgreSQL
SELECT
s.option_name,
s.option_value
FROM
information_schema.database_options s
WHERE
s.schema_name='public'
AND s.option_name IN ('optimizer_version',
'optimizer_statistics_package')
使用客户端库设置优化器选项
通过客户端库以编程方式与 Spanner 进行交互时,可以通过多种方式更改客户端应用的查询选项。
您必须使用最新版本的客户端库来设置优化器选项。
为数据库客户端设置优化器选项
应用可以通过配置查询选项属性,在客户端库上全局设置优化器选项,如以下代码段所示。优化器设置存储在客户端实例中,并应用于在客户端的整个生命周期内运行的所有查询。虽然这些选项在后端的数据库级别应用,但在客户端级别设置这些选项时,它们将应用于连接到该客户端的所有数据库。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
使用环境变量设置优化器选项
如需更轻松地尝试不同的优化器设置,而无需重新编译应用,您可以设置 SPANNER_OPTIMIZER_VERSION
和 SPANNER_OPTIMIZER_STATISTICS_PACKAGE
环境变量并运行应用,如以下代码段所示。
Linux/macOS
export SPANNER_OPTIMIZER_VERSION="7"
export SPANNER_OPTIMIZER_STATISTICS_PACKAGE="auto_20191128_14_47_22UTC"
Windows
set SPANNER_OPTIMIZER_VERSION="7"
set SPANNER_OPTIMIZER_STATISTICS_PACKAGE="auto_20191128_14_47_22UTC"
在客户端初始化时,系统会读取指定的查询优化器选项值并将其存储在客户端实例中,这些值将应用于在客户端的整个生命周期内运行的所有查询。
为客户端查询设置优化器选项
通过在构建查询时指定查询选项属性,您可以在客户端应用的查询级层为优化器版本或统计信息软件包版本指定值。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
使用语句提示为查询设置优化器选项
语句提示是对查询语句的提示,会更改查询执行的默认行为。在语句上设置 OPTIMIZER_VERSION
提示会强制使用指定的查询优化器版本运行该查询。
OPTIMIZER_VERSION
提示具有最高的优化器版本优先级。如果指定了语句提示,则将使用该提示,而不考虑其他所有优化器版本设置。
GoogleSQL
@{OPTIMIZER_VERSION=7} SELECT * FROM MyTable;
PostgreSQL
/*@OPTIMIZER_VERSION=7*/ SELECT * FROM MyTable;
您还可以使用 latest_version 字面量将查询的优化器版本设置为最新版本,如此处所示。
GoogleSQL
@{OPTIMIZER_VERSION=latest_version} SELECT * FROM MyTable;
PostgreSQL
/*@OPTIMIZER_VERSION=latest_version*/ SELECT * FROM MyTable;
在语句上设置 OPTIMIZER_STATISTICS_PACKAGE
提示会强制使用指定的查询优化器统计信息软件包版本运行该查询。指定的软件包必须停用垃圾回收:
GoogleSQL
ALTER STATISTICS <package_name> SET OPTIONS (allow_gc=false)
PostgreSQL
ALTER STATISTICS spanner."package_name" SET OPTIONS (allow_gc=false)
OPTIMIZER_STATISTICS_PACKAGE
提示具有最高的优化器软件包设置优先级。如果指定了语句提示,则将会忽略所有其他优化器软件包版本设置,使用该提示。
@{OPTIMIZER_STATISTICS_PACKAGE=auto_20191128_14_47_22UTC} SELECT * FROM MyTable;
您还可以通过 latest 字面量来使用最新的统计信息软件包。
@{OPTIMIZER_STATISTICS_PACKAGE=latest} SELECT * FROM MyTable;
这两个提示都可以在单个语句中设置,如以下示例所示。
default_version 字面量会将查询的优化器版本设置为默认版本,此版本可能与最新版本不同。如需了解详情,请参阅默认版本。
GoogleSQL
@{OPTIMIZER_VERSION=default_version, OPTIMIZER_STATISTICS_PACKAGE=auto_20191128_14_47_22UTC} SELECT * FROM MyTable;
PostgreSQL
/*@OPTIMIZER_VERSION=default_version, OPTIMIZER_STATISTICS_PACKAGE=auto_20191128_14_47_22UTC*/ SELECT * FROM KeyValue;
使用 Spanner JDBC 驱动程序时设置优化器选项
您可以通过在 JDBC 连接字符串中指定选项来替换优化器版本和统计信息软件包的默认值,如以下示例所示。
只有最新版 Spanner JDBC 驱动程序才支持这些选项。
您还可以使用 SET OPTIMIZER_VERSION
语句设置查询优化器版本,如以下示例所示。
如需详细了解如何使用开源驱动程序,请参阅使用开源 JDBC 驱动程序。
无效优化器版本的处理方式
Spanner 支持一系列优化器版本。
在查询优化器更新时,此范围会随着时间而改变。如果您指定的版本超出范围,则查询会失败。例如,如果您尝试使用语句提示 @{OPTIMIZER_VERSION=8}
运行查询,但最新的优化器版本号只有 7
,则 Spanner 会返回以下错误消息:
Query optimizer version: 8 is not
supported
处理无效的优化工具统计信息包设置
您可以使用本页前面介绍的方法之一,将数据库或查询固定到任何可用的统计信息软件包。如果提供无效的统计信息软件包名称,查询会失败。查询指定的统计信息软件包必须是:
确定用于运行查询的查询优化器版本
您可以通过 Google Cloud 控制台和 Google Cloud CLI 查看用于查询的优化器版本。
Google Cloud 控制台
如需查看用于查询的优化器版本,请在 Google Cloud 控制台的 Spanner Studio 页面中运行查询,然后选择说明标签页。您应该会看到如下所示的消息:
查询优化器版本:7
gcloud CLI
如需查看在 gcloud CLI 中运行查询时使用的版本,请将 --query-mode
标志设置为 PROFILE
,如以下代码段所示。
gcloud spanner databases execute-sql MyDatabase --instance=test-instance \
--query-mode=PROFILE --sql='SELECT * FROM MyTable'
在 Metrics Explorer 中直观呈现查询优化器版本
Cloud Monitoring 会收计量结果,以帮助您了解应用和系统服务的性能。为 Spanner 收集的指标之一是查询次数,它衡量实例中的查询数,随时间的抽样情况。此指标可帮助我们查看按错误代码分组的查询,此外,我们还可以使用它来查看运行每个查询的优化器版本。
您可以使用 Google Cloud 控制台中的 Metrics Explorer 直观呈现数据库实例的查询次数。图 1 显示了三个数据库的查询计数。您可以查看每个数据库中正在使用的优化器版本。
此图表下方的表格显示,my-db-1
尝试使用无效优化器版本运行查询,返回状态 Bad usage,结果查询计数为 0。其他数据库分别使用优化器版本 1 和版本 2 运行查询。
图 1:Metrics Explorer 中显示的按优化器版本分组的查询的查询计数。
要为您的实例设置类似的图表,请执行以下操作:
- 在 Google Cloud 控制台中,前往 Metrics Explorer。
- 在资源类型字段中,选择
Cloud Spanner Instance
。 - 在指标字段中,选择
Count of queries
。 - 在分组依据字段中,选择
database
、optimizer_version
和status
。
本示例中未显示同一数据库的不同查询使用不同优化器版本的情况。在这种情况下,图表会针对数据库和优化器的每个组合显示条形图。
如需了解如何使用 Cloud Monitoring 来监控 Spanner 实例,请参阅使用 Cloud Monitoring 进行监控