Como gerenciar o otimizador de consultas

O Cloud Spanner fornece controle do otimizador por meio do controle de versão do otimizador de consultas. Este guia mostra como gerenciar a versão do otimizador de consultas que suas consultas usam.

Conforme implementamos as atualizações do otimizador de consultas do Cloud Spanner, nosso objetivo é melhorar os planos de execução de consultas e oferecer um desempenho melhor para suas consultas. Por padrão, o Cloud Spanner usa a versão mais recente do otimizador de consultas para cada banco de dados. Com o controle de versão do otimizador de consultas, é possível executar consultas em uma versão mais antiga do otimizador que oferece desempenho previsível.

Listar versões compatíveis do otimizador

A versão do otimizador de consultas é um valor inteiro, com aumento de 1 a cada atualização. A versão mais recente do otimizador de consultas é 2.

Execute a instrução SQL a seguir para retornar uma lista de todas as versões compatíveis do otimizador, juntamente com as datas de lançamento correspondentes. O maior número de versão retornado é a versão compatível mais recente do otimizador.

SELECT * FROM SPANNER_SYS.SUPPORTED_OPTIMIZER_VERSIONS

Por padrão, o Cloud Spanner usa a versão mais recente do otimizador, que atualmente é 2. Use um dos métodos descritos neste guia para modificar esse comportamento padrão para seu cenário.

Para ver detalhes sobre cada versão, consulte o Histórico de versões do otimizador de consultas.

Prioridade de substituição de versão

O Cloud Spanner oferece várias maneiras de alterar a versão do otimizador. Por exemplo, você pode definir a versão de uma consulta específica ou configurá-la na biblioteca de cliente no nível do processo ou da consulta. Quando a versão é definida de várias maneiras, a seguinte ordem de preferência é aplicada. Selecione um link para ir para a seção correspondente no documento.

Padrão do Cloud Spanner ← opção de banco de dadosaplicativo clientevariável de ambienteconsulta do clientedica de instrução

Podemos interpretar a ordem de prioridades acima da seguinte maneira: quando você cria um banco de dados, ele usa a versão otimizada padrão do Cloud Spanner, que é sempre a versão mais recente. A configuração da versão do otimizador usando um dos métodos listados acima tem prioridade sobre qualquer item à esquerda dela. Por exemplo, a configuração do otimizador para um aplicativo usando uma variável de ambiente tem prioridade sobre qualquer valor definido para o banco de dados usando a opção de banco de dados. Definir a versão do otimizador por meio de uma dica de instrução tem a maior prioridade para a consulta especificada, prevalecendo sobre o valor definido com qualquer outro método.

Agora, analisaremos cada método mais detalhadamente.

Definir a versão do otimizador para um banco de dados usando ALTER DATABASE

Você pode definir a versão padrão do otimizador em um banco de dados usando o seguinte comando DDL ALTER DATABASE.

ALTER DATABASE MyDatabase
SET OPTIONS (optimizer_version = 2);

Execute o ALTER DATABASE no gcloud spanner com o comando gcloud spanner databases ddl update da seguinte maneira.

gcloud spanner databases ddl update MyDatabase --instance=test-instance \
    --ddl='ALTER DATABASE MyDatabase SET OPTIONS ( optimizer_version = 2 )'

Especificar a opção de banco de dados como NULL faz ele ser limpo e definir a versão mais recente como padrão. Esse é o padrão para novos bancos de dados.

Para ver o valor atual dessa opção para um banco de dados, leia-o na visualização INFORMATION_SCHEMA.DATABASE_OPTIONS.

Definir a versão do otimizador para um app cliente

Quando você interage de maneira programática com o Cloud Spanner por meio de bibliotecas de cliente, há várias maneiras de alterar a versão do otimizador para seu aplicativo cliente.

Um aplicativo pode definir uma opção de consulta global na biblioteca de cliente configurando a propriedade de opções de consulta, conforme mostrado nos snippets de código a seguir. A configuração da versão do otimizador é armazenada na instância do cliente e aplicada a todas as consultas executadas durante a vida útil do cliente. Mesmo que as opções se apliquem no nível do banco de dados no back-end, quando as opções são definidas no nível do cliente, elas se aplicam a todos os bancos de dados conectados por meio desse cliente.

C++

namespace spanner = ::google::cloud::spanner;
spanner::Client client(
    spanner::MakeConnection(db),
    spanner::ClientOptions().set_query_options(
        spanner::QueryOptions().set_optimizer_version("1")));

C#

var builder = new SpannerConnectionStringBuilder
{
    DataSource = $"projects/{projectId}/instances/{instanceId}/databases/{databaseId}"
};
// Create connection to Cloud Spanner.
using (var connection = new SpannerConnection(builder))
{
    // Set query options on the connection.
    connection.QueryOptions = QueryOptions.Empty.WithOptimizerVersion("1");
    var cmd = connection.CreateSelectCommand(
        "SELECT SingerId, AlbumId, AlbumTitle FROM Albums");
    using (var reader = await cmd.ExecuteReaderAsync())
    {
        while (await reader.ReadAsync())
        {
            Console.WriteLine("SingerId : "
            + reader.GetFieldValue<string>("SingerId")
            + " AlbumId : "
            + reader.GetFieldValue<string>("AlbumId")
            + " AlbumTitle : "
            + reader.GetFieldValue<string>("AlbumTitle"));
        }
    }
}

Go


import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/spanner"
	"google.golang.org/api/iterator"
	sppb "google.golang.org/genproto/googleapis/spanner/v1"
)

func createClientWithQueryOptions(w io.Writer, database string) error {
	ctx := context.Background()
	queryOptions := spanner.QueryOptions{
		Options: &sppb.ExecuteSqlRequest_QueryOptions{OptimizerVersion: "1"},
	}
	client, err := spanner.NewClientWithConfig(
		ctx, database, spanner.ClientConfig{QueryOptions: queryOptions},
	)
	if err != nil {
		return err
	}
	defer client.Close()

	stmt := spanner.Statement{SQL: `SELECT VenueId, VenueName, LastUpdateTime FROM Venues`}
	iter := client.Single().Query(ctx, stmt)
	defer iter.Stop()
	for {
		row, err := iter.Next()
		if err == iterator.Done {
			return nil
		}
		if err != nil {
			return err
		}
		var venueID int64
		var venueName string
		var lastUpdateTime time.Time
		if err := row.Columns(&venueID, &venueName, &lastUpdateTime); err != nil {
			return err
		}
		fmt.Fprintf(w, "%d %s %s\n", venueID, venueName, lastUpdateTime)
	}
}

Java

static void clientWithQueryOptions(DatabaseId db) {
  SpannerOptions options =
      SpannerOptions.newBuilder()
          .setDefaultQueryOptions(
              db, QueryOptions.newBuilder().setOptimizerVersion("1").build())
          .build();
  Spanner spanner = options.getService();
  DatabaseClient dbClient = spanner.getDatabaseClient(db);
  try (ResultSet resultSet =
      dbClient
          .singleUse()
          .executeQuery(Statement.of("SELECT SingerId, AlbumId, AlbumTitle FROM Albums"))) {
    while (resultSet.next()) {
      System.out.printf(
          "%d %d %s\n", resultSet.getLong(0), resultSet.getLong(1), resultSet.getString(2));
    }
  }
}

Node.js

// Imports the Google Cloud client library
const {Spanner} = require('@google-cloud/spanner');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const databaseId = 'my-database';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance and database
const instance = spanner.instance(instanceId);
const database = instance.database(databaseId, {}, {optimizerVersion: '1'});

const query = {
  sql: `SELECT AlbumId, AlbumTitle, MarketingBudget
        FROM Albums
        ORDER BY AlbumTitle`,
};

// Queries rows from the Albums table
try {
  const [rows] = await database.run(query);

  rows.forEach(row => {
    const json = row.toJSON();
    const marketingBudget = json.MarketingBudget
      ? json.MarketingBudget
      : null; // This value is nullable
    console.log(
      `AlbumId: ${json.AlbumId}, AlbumTitle: ${json.AlbumTitle}, MarketingBudget: ${marketingBudget}`
    );
  });
} catch (err) {
  console.error('ERROR:', err);
} finally {
  // Close the database when finished.
  database.close();
}

PHP

use Google\Cloud\Spanner\SpannerClient;
use Google\Cloud\Spanner\Database;

/**
 * Create a client with query options.
 * Example:
 * ```
 * create_client_with_query_options($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function create_client_with_query_options($instanceId, $databaseId)
{
    $spanner = new SpannerClient([
        'queryOptions' => [
            'optimizerVersion' => "1"
        ]
    ]);
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $results = $database->execute(
        'SELECT VenueId, VenueName, LastUpdateTime FROM Venues'
    );

    foreach ($results as $row) {
        printf('VenueId: %s, VenueName: %s, LastUpdateTime: %s' . PHP_EOL,
            $row['VenueId'], $row['VenueName'], $row['LastUpdateTime']);
    }
}

Python

# instance_id = "your-spanner-instance"
# database_id = "your-spanner-db-id"
spanner_client = spanner.Client(
    query_options={'optimizer_version': '1'}
)
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)

with database.snapshot() as snapshot:
    results = snapshot.execute_sql(
        'SELECT VenueId, VenueName, LastUpdateTime FROM Venues'
    )

    for row in results:
        print(u"VenueId: {}, VenueName: {}, LastUpdateTime: {}".format(
            *row))

Ruby

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

query_options = { optimizer_version: "1" }

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id, query_options: query_options

sql_query = "SELECT VenueId, VenueName, LastUpdateTime FROM Venues"

client.execute(sql_query).rows.each do |row|
  puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:LastUpdateTime]}"
end

Definir a versão do otimizador para um app cliente usando uma variável de ambiente

Para facilitar o teste de diferentes versões do otimizador sem precisar recompilar seu app, defina a variável de ambiente SPANNER_OPTIMIZER_VERSION e execute o app, como mostra o snippet a seguir.

Linux/macOS

export SPANNER_OPTIMIZER_VERSION="2"

Windows

set SPANNER_OPTIMIZER_VERSION="2"

O valor da versão do otimizador de consultas especificado é lido e armazenado na instância do cliente no momento da inicialização e aplicado a todas as consultas executadas durante a vida útil do cliente.

Definir a versão do otimizador para uma consulta do cliente

Você pode estipular um valor para a versão do otimizador no nível da consulta no aplicativo cliente especificando uma propriedade de opções de consulta ao criá-la. Isso é ilustrado nos snippets de código a seguir para cada linguagem compatível.

C++

namespace spanner = ::google::cloud::spanner;
auto sql = spanner::SqlStatement("SELECT SingerId, FirstName FROM Singers");
auto opts = spanner::QueryOptions().set_optimizer_version("1");
auto rows = client.ExecuteQuery(std::move(sql), std::move(opts));

C#

var builder = new SpannerConnectionStringBuilder
{
    DataSource = $"projects/{projectId}/instances/{instanceId}/databases/{databaseId}"
};
// Create connection to Cloud Spanner.
using (var connection = new SpannerConnection(builder))
{
    var cmd = connection.CreateSelectCommand(
        "SELECT SingerId, AlbumId, AlbumTitle FROM Albums");
    // Set query options just for this command.
    cmd.QueryOptions = QueryOptions.Empty.WithOptimizerVersion("1");
    using (var reader = await cmd.ExecuteReaderAsync())
    {
        while (await reader.ReadAsync())
        {
            Console.WriteLine("SingerId : "
            + reader.GetFieldValue<string>("SingerId")
            + " AlbumId : "
            + reader.GetFieldValue<string>("AlbumId")
            + " AlbumTitle : "
            + reader.GetFieldValue<string>("AlbumTitle"));
        }
    }
}

Go


import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/spanner"
	"google.golang.org/api/iterator"
	sppb "google.golang.org/genproto/googleapis/spanner/v1"
)

func queryWithQueryOptions(w io.Writer, db string) error {
	ctx := context.Background()
	client, err := spanner.NewClient(ctx, db)
	if err != nil {
		return err
	}
	defer client.Close()

	stmt := spanner.Statement{SQL: `SELECT VenueId, VenueName, LastUpdateTime FROM Venues`}
	queryOptions := spanner.QueryOptions{
		Options: &sppb.ExecuteSqlRequest_QueryOptions{OptimizerVersion: "1"},
	}
	iter := client.Single().QueryWithOptions(ctx, stmt, queryOptions)
	defer iter.Stop()
	for {
		row, err := iter.Next()
		if err == iterator.Done {
			return nil
		}
		if err != nil {
			return err
		}
		var venueID int64
		var venueName string
		var lastUpdateTime time.Time
		if err := row.Columns(&venueID, &venueName, &lastUpdateTime); err != nil {
			return err
		}
		fmt.Fprintf(w, "%d %s %s\n", venueID, venueName, lastUpdateTime)
	}
}

Java

static void queryWithQueryOptions(DatabaseClient dbClient) {
  try (ResultSet resultSet =
      dbClient
          .singleUse()
          .executeQuery(
              Statement
                  .newBuilder("SELECT SingerId, AlbumId, AlbumTitle FROM Albums")
                  .withQueryOptions(QueryOptions.newBuilder().setOptimizerVersion("1").build())
                  .build())) {
    while (resultSet.next()) {
      System.out.printf(
          "%d %d %s\n", resultSet.getLong(0), resultSet.getLong(1), resultSet.getString(2));
    }
  }
}

Node.js

// Imports the Google Cloud client library
const {Spanner} = require('@google-cloud/spanner');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const databaseId = 'my-database';

// Creates a client
const spanner = new Spanner({
  projectId: projectId,
});

// Gets a reference to a Cloud Spanner instance and database
const instance = spanner.instance(instanceId);
const database = instance.database(databaseId);

const query = {
  sql: `SELECT AlbumId, AlbumTitle, MarketingBudget
        FROM Albums
        ORDER BY AlbumTitle`,
  queryOptions: {
    optimizerVersion: 'latest',
  },
};

// Queries rows from the Albums table
try {
  const [rows] = await database.run(query);

  rows.forEach(row => {
    const json = row.toJSON();
    const marketingBudget = json.MarketingBudget
      ? json.MarketingBudget
      : null; // This value is nullable
    console.log(
      `AlbumId: ${json.AlbumId}, AlbumTitle: ${json.AlbumTitle}, MarketingBudget: ${marketingBudget}`
    );
  });
} catch (err) {
  console.error('ERROR:', err);
} finally {
  // Close the database when finished.
  database.close();
}

PHP

use Google\Cloud\Spanner\SpannerClient;
use Google\Cloud\Spanner\Database;

/**
 * Queries sample data using SQL with query options.
 * Example:
 * ```
 * query_data_with_query_options($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function query_data_with_query_options($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $results = $database->execute(
        'SELECT VenueId, VenueName, LastUpdateTime FROM Venues',
        [
            'queryOptions' => [
                'optimizerVersion' => "1"
            ]
        ]
    );

    foreach ($results as $row) {
        printf('VenueId: %s, VenueName: %s, LastUpdateTime: %s' . PHP_EOL,
            $row['VenueId'], $row['VenueName'], $row['LastUpdateTime']);
    }
}

Python

# instance_id = "your-spanner-instance"
# database_id = "your-spanner-db-id"
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)

with database.snapshot() as snapshot:
    results = snapshot.execute_sql(
        'SELECT VenueId, VenueName, LastUpdateTime FROM Venues',
        query_options={'optimizer_version': '1'}
    )

    for row in results:
        print(u"VenueId: {}, VenueName: {}, LastUpdateTime: {}".format(
            *row))

Ruby

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

sql_query = "SELECT VenueId, VenueName, LastUpdateTime FROM Venues"
query_options = { optimizer_version: "1" }

client.execute(sql_query, query_options: query_options).rows.each do |row|
  puts "#{row[:VenueId]} #{row[:VenueName]} #{row[:LastUpdateTime]}"
end

Definir a versão do otimizador para uma consulta usando uma dica de instrução

Uma dica de instrução é uma dica em uma instrução de consulta que altera a execução da consulta do comportamento padrão. Definir a dica OPTIMIZER_VERSION em uma instrução força essa consulta a ser executada usando a versão especificada do otimizador de consultas.

A dica OPTIMIZER_VERSION tem a maior prioridade de versão do otimizador. Se a dica de instrução for especificada, ela será usada independentemente de todas as outras configurações de versão do otimizador.

@{OPTIMIZER_VERSION=2} SELECT * FROM MyTable

Você também pode usar o literal latest para definir a versão do otimizador de uma consulta como a versão mais recente, como mostrado aqui.

@{OPTIMIZER_VERSION=latest} SELECT * FROM MyTable

Definir a versão do otimizador usando o driver JDBC

Você pode substituir o valor padrão da versão do otimizador especificando uma versão na string de conexão JDBC, conforme mostrado no exemplo a seguir.

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

class ConnectionWithQueryOptionsExample {

  static void connectionWithQueryOptions() throws SQLException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project";
    String instanceId = "my-instance";
    String databaseId = "my-database";
    connectionWithQueryOptions(projectId, instanceId, databaseId);
  }

  @SuppressFBWarnings(
      value = "OBL_UNSATISFIED_OBLIGATION",
      justification = "https://github.com/spotbugs/spotbugs/issues/293")
  static void connectionWithQueryOptions(String projectId, String instanceId, String databaseId)
      throws SQLException {
    String optimizerVersion = "1";
    String connectionUrl =
        String.format(
            "jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s?optimizerVersion=%s",
            projectId, instanceId, databaseId, optimizerVersion);
    try (Connection connection = DriverManager.getConnection(connectionUrl);
        Statement statement = connection.createStatement()) {
      // Execute a query using the optimizer version '1'.
      try (ResultSet rs =
          statement.executeQuery(
              "SELECT SingerId, FirstName, LastName FROM Singers ORDER BY LastName")) {
        while (rs.next()) {
          System.out.printf("%d %s %s%n", rs.getLong(1), rs.getString(2), rs.getString(3));
        }
      }
      try (ResultSet rs = statement.executeQuery("SHOW VARIABLE OPTIMIZER_VERSION")) {
        while (rs.next()) {
          System.out.printf("Optimizer version: %s%n", rs.getString(1));
        }
      }
    }
  }
}

Também é possível definir a versão do otimizador de consultas usando a instrução SET OPTIMIZER_VERSION, conforme mostrado no exemplo a seguir.

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

class SetQueryOptionsExample {

  static void setQueryOptions() throws SQLException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project";
    String instanceId = "my-instance";
    String databaseId = "my-database";
    setQueryOptions(projectId, instanceId, databaseId);
  }

  @SuppressFBWarnings(
      value = "OBL_UNSATISFIED_OBLIGATION",
      justification = "https://github.com/spotbugs/spotbugs/issues/293")
  static void setQueryOptions(String projectId, String instanceId, String databaseId)
      throws SQLException {
    String connectionUrl =
        String.format(
            "jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s",
            projectId, instanceId, databaseId);
    try (Connection connection = DriverManager.getConnection(connectionUrl);
        Statement statement = connection.createStatement()) {
      // Instruct the JDBC connection to use version '1' of the query optimizer.
      statement.execute("SET OPTIMIZER_VERSION='1'");
      // Execute a query using the latest optimizer version.
      try (ResultSet rs =
          statement.executeQuery(
              "SELECT SingerId, FirstName, LastName FROM Singers ORDER BY LastName")) {
        while (rs.next()) {
          System.out.printf("%d %s %s%n", rs.getLong(1), rs.getString(2), rs.getString(3));
        }
      }
      try (ResultSet rs = statement.executeQuery("SHOW VARIABLE OPTIMIZER_VERSION")) {
        while (rs.next()) {
          System.out.printf("Optimizer version: %s%n", rs.getString(1));
        }
      }
    }
  }
}

Para mais detalhes sobre como usar o driver de código aberto, consulte Como usar o driver JDBC de código aberto.

Como as versões inválidas do otimizador são processadas

O Cloud Spanner é compatível com uma variedade de versões do otimizador. Essas variedade muda ao longo do tempo quando o otimizador de consultas é atualizado. Se a versão especificada ao usar um dos métodos descritos neste guia estiver fora do conjunto de opções, o Cloud Spanner falhará na consulta. Por exemplo, se você tentar executar uma consulta com a versão do otimizador = 100 e, supondo que exceda o valor máximo atual, você receberá o erro abaixo.

Query optimizer version: 100 is not supported

Determinar a versão do otimizador de consultas usada para executar uma consulta

A versão do otimizador usada para uma consulta é visível no gcloud spanner e por meio do Console do Cloud.

gcloud spanner

Para ver a versão usada ao executar uma consulta no gcloud spanner, defina a sinalização --query-mode como PROFILE, conforme mostrado no snippet a seguir.

gcloud spanner databases execute-sql MyDatabase --instance=test-instance \
    --query-mode=PROFILE --sql='SELECT * FROM MyTable'

Cloud Console

Para ver a versão do otimizador usada em uma consulta, execute a consulta na visualização Banco de dados de consulta do Console do Cloud e selecione a guia Explicação. Você verá uma mensagem semelhante a esta:

Esta consulta foi executada com a versão 2 do otimizador

Visualizar a versão do otimizador de consultas no Metrics Explorer

O Cloud Monitoring coleta medições para ajudar você a entender o desempenho dos seus aplicativos e serviços do sistema. Uma das métricas coletadas para o Cloud Spanner é Contagem de consultas, que mede o número de consultas em uma instância, amostrado ao longo do tempo. Embora essa métrica seja muito útil para ver consultas agrupadas por código de erro, é possível usá-la para ver qual versão do otimizador foi usada para executar cada consulta.

Use o Metrics Explorer no Console do Cloud para visualizar a Contagem de consultas da instância do banco de dados. A Figura 1 mostra a contagem de consultas para três bancos de dados. Você pode ver qual versão do otimizador está sendo usada em cada banco de dados.

A tabela abaixo do gráfico na figura mostra que my-db-1 tentou executar uma consulta com uma versão inválida do otimizador, retornando o status Uso inválido e resultando em uma contagem de consulta de 0. Os outros bancos de dados executaram consultas usando as versões 1 e 2 do otimizador, respectivamente.

Contagem de consultas no Metrics Explorer agrupadas pela versão do otimizador de consulta

Figura 1. Contagem de consultas exibidas no Metrics Explorer com consultas agrupadas pela versão do otimizador.

Para configurar um gráfico semelhante para a instância:

  1. Navegue até o Metrics Explorer no Console do Cloud.
  2. No campo Tipo de recurso, selecione Cloud Spanner Instance.
  3. No campo Métrica, selecione Count of queries.
  4. No campo Agrupar por, selecione database, optimizer_version e status.

Não mostrado neste exemplo é o caso em que uma versão diferente do otimizador está sendo usada para diferentes consultas no mesmo banco de dados. Nesse caso, o gráfico exibirá um segmento de barras para cada combinação de banco de dados e versão do otimizador.

Para saber como usar o Cloud Monitoring para monitorar suas instâncias do Cloud Spanner, consulte Como monitorar com o Cloud Monitoring.