Neste documento, descrevemos as estatísticas de consulta que o Spanner oferece como tabelas
integradas. É possível recuperar estatísticas das tabelas SPANNER_SYS.QUERY_STATS*
usando instruções SQL.
Quando usar as estatísticas de consulta
As estatísticas de consulta são úteis quando você precisa investigar problemas de desempenho ou otimizar consultas no banco de dados do Spanner. Use as estatísticas de consulta para investigar o alto uso da CPU, resolver problemas de latência de consulta elevada ou reduzir o uso da memória.
Como acessar as estatísticas de consulta
O Spanner fornece as estatísticas de consulta no esquema SPANNER_SYS. É possível usar as seguintes maneiras de acessar os dados do SPANNER_SYS:
A página do Spanner Studio de um banco de dados no console do Google Cloud .
O comando
gcloud spanner databases execute-sql.O painel Query Insights.
O método
executeSqlouexecuteStreamingSql.
Os seguintes métodos de leitura única fornecidos pelo Spanner não
são compatíveis com SPANNER_SYS:
- realizar uma leitura forte de uma única linha ou de várias linhas em uma tabela;
- realizar uma leitura desatualizada de uma única linha ou várias linhas em uma tabela;
- ler uma única linha ou várias linhas em um índice secundário.
Para mais informações, consulte Métodos de leitura única.
Uso de CPU agrupado por consulta
As tabelas a seguir rastreiam as consultas com o maior uso de CPU durante um período específico:
SPANNER_SYS.QUERY_STATS_TOP_MINUTE: consultas durante intervalos de 1 minutoSPANNER_SYS.QUERY_STATS_TOP_10MINUTE: consultas durante intervalos de 10 minutosSPANNER_SYS.QUERY_STATS_TOP_HOUR: consultas durante intervalos de 1 hora
Essas tabelas têm as seguintes propriedades:
Cada tabela contém dados de intervalos de tempo não sobrepostos da duração especificada pelo nome da tabela.
Os intervalos são baseados em horários do relógio
- Os intervalos de 1 minuto terminam no minuto.
- Os intervalos de 10 minutos terminam a cada 10 minutos, começando na hora cheia.
- Os intervalos de 1 hora terminam na hora cheia.
Por exemplo, às 11:59:30, os intervalos mais recentes disponíveis para as consultas SQL são:
- 1 minuto: 11:58:00–11:58:59
- 10 minutos: 11:40:00–11:49:59
- 1 hora: 10:00:00–10:59:59
O Spanner agrupa as estatísticas pelo texto da consulta SQL. Se uma consulta usar parâmetros de consulta ou se o Spanner converter automaticamente valores literais em parâmetros, o Spanner vai agrupar todas as execuções dessa consulta em uma linha. Se a consulta usar literais de string que não podem ser convertidos automaticamente em parâmetros, o Spanner só agrupará as estatísticas se o texto completo da consulta for idêntico. Quando qualquer texto for diferente, cada consulta aparecerá como uma linha separada. Para DML em lote, o Spanner normaliza o lote eliminando a duplicação de instruções idênticas consecutivas antes de gerar a impressão digital.
Se uma tag de solicitação estiver presente, TEXT_FINGERPRINT será o hash da tag de solicitação. Caso contrário, será o hash do valor
TEXT. Para DMLs particionadas, TEXT_FINGERPRINT é sempre o hash do valorTEXT.Cada linha contém estatísticas de todas as execuções de uma consulta SQL específica para as quais o Spanner captura estatísticas durante o intervalo especificado.
Se o Spanner não conseguir armazenar todas as consultas executadas durante o intervalo, o sistema priorizará as consultas com o maior uso de CPU durante o intervalo especificado.
As consultas rastreadas incluem aquelas que foram concluídas, falharam ou foram canceladas pelo usuário.
Um subconjunto de estatísticas é específico das consultas que foram executadas, mas não foram concluídas:
Contagem de execuções e latência média em segundos em todas as consultas que não foram bem-sucedidas.
Contagem de execução para consultas que expiraram.
Contagem de execuções para consultas que foram canceladas pelo usuário ou falharam devido a problemas de conectividade de rede.
Todas as colunas nas tabelas podem ser nulas.
As estatísticas de consulta para instruções DML particionadas executadas anteriormente têm as seguintes propriedades:
Cada instrução DML particionada bem-sucedida conta estritamente como uma execução. Uma instrução DML particionada que falhou, foi cancelada ou está em execução tem uma contagem de execução igual a zero.
As estatísticas
ALL_FAILED_EXECUTION_COUNT,ALL_FAILED_AVG_LATENCY_SECONDS,CANCELLED_OR_DISCONNECTED_EXECUTION_COUNTeTIMED_OUT_EXECUTION_COUNTnão são rastreadas para DMLs particionadas.As estatísticas de cada instrução DML particionada executada anteriormente podem aparecer em intervalos diferentes.
SPANNER_SYS.QUERY_STATS_TOP_10MINUTEeSPANNER_SYS.QUERY_STATS_TOP_HOURfornecem uma visualização agregada para instruções DML particionadas que são concluídas em 10 minutos e 1 hora, respectivamente. Para ver estatísticas de instruções com duração superior a 1 hora, consulte o exemplo de consulta.
Esquema de tabela
| Nome da coluna | Tipo | Descrição | |
|---|---|---|---|
INTERVAL_END |
TIMESTAMP |
Fim do intervalo de tempo em que as execuções de consultas incluídas ocorreram. | |
REQUEST_TAG |
STRING |
A tag de solicitação opcional para essa operação de consulta. Para mais informações sobre como usar tags, consulte Solução de problemas com tags de solicitação. | |
QUERY_TYPE |
STRING |
Indica se uma consulta é PARTITIONED_QUERY ou QUERY. Uma PARTITIONED_QUERY
é uma consulta com um partitionToken obtido da
API PartitionQuery
ou uma instrução DML particionada. Todas as outras consultas e instruções DML são indicadas pelo tipo de consulta QUERY.
|
|
TEXT |
STRING |
Texto de consulta SQL, truncado para aproximadamente 64 KB.
As estatísticas de várias consultas que têm a mesma string de tag são agrupadas em uma única linha com o REQUEST_TAG correspondente a essa string de tag. Somente o texto de uma dessas consultas é mostrado
neste campo, truncado para aproximadamente 64 KB.
Para DML em lote, o conjunto de instruções SQL é nivelado em uma única linha, concatenada usando um delimitador de ponto e vírgula. Textos SQL idênticos consecutivos são deduplicados antes do truncamento.
|
|
TEXT_TRUNCATED |
BOOL |
Se o texto da consulta foi truncado ou não. | |
TEXT_FINGERPRINT |
INT64 |
O hash do valor REQUEST_TAG, se presente; Caso contrário,
o hash do valor TEXT.
Corresponde ao campo query_fingerprint no registro de auditoria. |
|
EXECUTION_COUNT |
INT64 |
Número de vezes que o Spanner viu a consulta durante o intervalo. | |
AVG_LATENCY_SECONDS |
FLOAT64 |
Tempo médio, em segundos, para cada execução de consulta no banco de dados. Essa média exclui o tempo de codificação e transmissão do conjunto de resultados e também a sobrecarga. | |
AVG_ROWS |
FLOAT64 |
Número médio de linhas que a consulta retornou. | |
AVG_BYTES |
FLOAT64 |
Número médio de bytes de dados que a consulta retornou, excluindo a sobrecarga de codificação de transmissão. | |
AVG_ROWS_SCANNED |
FLOAT64 |
Número médio de linhas que a consulta verificou, com exceção dos valores excluídos. | |
AVG_CPU_SECONDS |
FLOAT64 |
Número médio de segundos de tempo de CPU que o Spanner gastou em todas as operações para executar a consulta. | |
ALL_FAILED_EXECUTION_COUNT |
INT64 |
Número de vezes que a consulta falhou durante o intervalo. | |
ALL_FAILED_AVG_LATENCY_SECONDS |
FLOAT64 |
Média de tempo, em segundos, para cada execução de consulta que falhou no banco de dados. Essa média exclui o tempo de codificação e transmissão do conjunto de resultados e também a sobrecarga. | |
CANCELLED_OR_DISCONNECTED_EXECUTION_COUNT |
INT64 |
Número de vezes que a consulta foi cancelada pelo usuário ou falhou devido a uma falha na conexão de rede durante o intervalo. | |
TIMED_OUT_EXECUTION_COUNT |
INT64 |
Número de vezes que a consulta expirou durante o intervalo. | |
AVG_BYTES_WRITTEN |
FLOAT64 |
Número médio de bytes gravados pela instrução. | |
AVG_ROWS_WRITTEN |
FLOAT64 |
Número médio de linhas modificadas pela instrução. | |
STATEMENT_COUNT |
INT64 |
A soma das instruções agregadas nesta entrada. Para consultas regulares e DML, isso é igual à contagem de execuções. Para DML em lote, o Spanner captura o número de instruções no lote. | |
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT |
INT64 |
O número de vezes que a consulta foi executada como parte de uma transação de leitura/gravação. Essa coluna ajuda a determinar se é possível evitar conflitos de bloqueio movendo a consulta para uma transação somente leitura. | |
LATENCY_DISTRIBUTION |
ARRAY<STRUCT> |
Um histograma do tempo de execução da consulta. Os valores são medidos em segundos.
A matriz contém um único elemento e tem o seguinte tipo:
Para calcular a latência do percentil com base na distribuição,
use a função Para mais informações, consulte Percentis e métricas com valor de distribuição. |
|
AVG_MEMORY_PEAK_USAGE_BYTES |
FLOAT64 |
Durante uma execução de consulta distribuída, o uso médio de pico de memória (em bytes). Use essa estatística para identificar quais consultas ou tamanhos de dados de tabela provavelmente vão atingir os limites de memória. |
|
AVG_MEMORY_USAGE_PERCENTAGE |
FLOAT64 |
Durante uma execução de consulta distribuída, o uso da memória médio necessário (como uma porcentagem do limite de memória permitido para essa consulta). Essa estatística rastreia apenas a memória necessária para a execução da consulta. Alguns operadores usam memória de buffer adicional para melhorar
o desempenho. A memória de buffer adicional usada é visível no plano de consulta, mas não é usada para calcular Use essa estatística para identificar consultas que estão se aproximando do limite de uso da memória e correm o risco de falhar se o tamanho dos dados aumentar. Para reduzir o risco de falha na consulta, consulte as práticas recomendadas de SQL para otimizar essas consultas ou divida a consulta em partes que leiam menos dados. |
|
AVG_QUERY_PLAN_CREATION_TIME_SECS |
FLOAT64 |
O tempo médio de CPU em segundos gasto na compilação da consulta, incluindo a criação do ambiente de execução da consulta. Se o valor dessa coluna for alto, use consultas parametrizadas. |
|
AVG_FILESYSTEM_DELAY_SECS |
FLOAT64 |
O tempo médio que a consulta gasta lendo o sistema de arquivos ou sendo bloqueada na entrada/saída (E/S). Use essa estatística para identificar uma possível latência alta causada pela E/S do sistema de arquivos. Para mitigar, adicione um índice
ou uma cláusula |
|
AVG_REMOTE_SERVER_CALLS |
FLOAT64 |
O número médio de chamadas de servidor remoto (RPC) que foram concluídas pela consulta. Use essa estatística para identificar se consultas diferentes que verificam o mesmo
número de linhas têm um número muito diferente de RPCs. A consulta com um
valor de RPC mais alto pode se beneficiar da adição de um índice
ou de uma
cláusula |
|
AVG_ROWS_SPOOLED |
FLOAT64 |
O número médio de linhas gravadas em um disco temporário (não na memória) pela instrução de consulta. Use essa estatística para identificar consultas de latência potencialmente alta
que consomem muita memória e não podem ser executadas na memória. Para mitigar,
mude a ordem de |
|
AVG_DISK_IO_COST |
FLOAT64 |
O custo médio dessa consulta em termos de carga de disco do HDD do Spanner. Use esse valor para fazer comparações relativas de custo de E/S de HDD entre as leituras executadas no banco de dados. A consulta de dados no armazenamento em HDD gera uma cobrança em relação à capacidade de carga do disco HDD da instância. Um valor mais alto indica que você está usando mais carga de disco HDD e que sua consulta pode ser mais lenta do que se estivesse sendo executada em SSD. Além disso, se a carga do disco HDD estiver no limite, o desempenho das consultas poderá ser ainda mais afetado. É possível monitorar a capacidade total de carga do disco HDD da instância como uma porcentagem. Para adicionar mais capacidade de carga de disco HDD, adicione mais unidades de processamento ou nós à instância. Para mais informações, consulte Alterar a capacidade de computação. Para melhorar o desempenho das consultas, considere também mover alguns dados para o SSD. Para cargas de trabalho que consomem muita E/S de disco, recomendamos que você armazene dados acessados com frequência no armazenamento SSD. Os dados acessados do SSD não consomem a capacidade de carga do disco HDD. É possível armazenar tabelas, colunas ou índices secundários seletivos no armazenamento SSD conforme necessário, mantendo os dados acessados com pouca frequência no armazenamento HDD. Para mais informações, consulte Visão geral do armazenamento em níveis. |
|
LATENCY_DISTRIBUTION_JSON_STRING |
STRING |
Um histograma do tempo de execução da consulta. Os valores são medidos em segundos. Uma representação de string compatível com JSON da estatística
Essa coluna é compatível com bancos de dados de dialeto GoogleSQL e PostgreSQL. Essa coluna contém a Distribuição. Para calcular a latência do percentil com base na distribuição, use a função
Para mais informações, consulte Percentis e métricas com valor de distribuição. |
|
AVG_COLUMNAR_READ_SHARE |
FLOAT64 |
A porcentagem média de bytes lidos do armazenamento colunar em relação ao total de bytes lidos do armazenamento baseado em linhas e colunar, expressa como uma fração entre 0 e 1. Use essa estatística para monitorar o uso do mecanismo colunar em consultas. Para mais informações, consulte Monitorar o desempenho do mecanismo colunar. |
|
QUERY_OPTIMIZER_VERSIONS |
ARRAY<INT64> |
As versões do otimizador de consultas usadas para as consultas nesse período. |
|
STATISTICS_PACKAGE_NAMES |
ARRAY<STRING> |
Os nomes dos pacotes de estatísticas usados para as consultas nessa janela de tempo. |
|
CPU_SECONDS_DISTRIBUTION |
ARRAY<STRUCT> |
Um histograma do tempo de CPU que o Spanner gastou em todas as operações para executar a consulta. Os valores são medidos em segundos.
A matriz tem a seguinte estrutura:
Para mais informações sobre os tipos de valor, consulte Distribuição e Exponencial. Para calcular os percentis de segundos de CPU da distribuição, use a função
|
|
CPU_SECONDS_DISTRIBUTION_JSON_STRING |
STRING |
Uma representação de string compatível com JSON da estatística Essa coluna é compatível com bancos de dados de dialeto GoogleSQL e PostgreSQL. Para calcular os percentis de segundos de CPU da distribuição, use a função
|
|
ROW_SCANNED_DISTRIBUTION |
ARRAY<STRUCT> |
Um histograma do número de linhas verificadas pela consulta, excluindo os valores excluídos.
A matriz tem a seguinte estrutura:
Para mais informações sobre os tipos de valor, consulte Distribuição e Exponencial. Para calcular percentis de linhas verificadas na distribuição, use
a
função
|
|
ROW_SCANNED_DISTRIBUTION_JSON_STRING |
STRING |
Uma representação de string compatível com JSON da estatística Essa coluna é compatível com bancos de dados de dialeto GoogleSQL e PostgreSQL. Para calcular percentis de linhas verificadas na distribuição, use
a
função
|
EXECUTION_COUNT, AVG_LATENCY_SECONDS, LATENCY_DISTRIBUTION
e LATENCY_DISTRIBUTION_JSON_STRING para consultas com falha
incluem consultas que falharam devido à sintaxe incorreta ou que encontraram um
erro temporário, mas foram bem-sucedidas na nova tentativa. Essas estatísticas não rastreiam instruções DML particionadas com falha e canceladas.
Agregar estatísticas
Também há tabelas que rastreiam dados agregados de todas as consultas para as quais o Spanner capturou estatísticas em um período específico:
SPANNER_SYS.QUERY_STATS_TOTAL_MINUTE: consultas durante intervalos de 1 minutoSPANNER_SYS.QUERY_STATS_TOTAL_10MINUTE: consultas em intervalos de 10 minutosSPANNER_SYS.QUERY_STATS_TOTAL_HOUR: consultas durante intervalos de 1 hora
Essas tabelas têm as seguintes propriedades:
Cada tabela contém dados de intervalos de tempo não sobrepostos do tamanho especificado pelo nome da tabela.
Os intervalos são baseados em tempos de relógio. Os de 1 minuto terminam no minuto, os de 10 minutos terminam a cada 10 minutos, começando na hora, e os intervalos de 1 hora terminam na hora.
Por exemplo, às 11:59:30, os intervalos mais recentes disponíveis para as consultas SQL são:
- 1 minuto: 11:58:00–11:58:59
- 10 minutos: 11:40:00–11:49:59
- 1 hora: 10:00:00–10:59:59
Cada linha contém estatísticas para todas as consultas executadas no banco de dados durante o intervalo especificado, agregadas juntas. Há apenas uma linha por intervalo de tempo e inclui consultas concluídas, consultas com falha e consultas canceladas pelo usuário.
As estatísticas capturadas nas tabelas
TOTALpodem incluir consultas que o Spanner não capturou nas tabelasTOP.Algumas colunas dessas tabelas são expostas como métricas no Cloud Monitoring. As métricas expostas são:
- Contagem de execuções de consulta
- Falhas de consulta
- Latências de consulta
- Contagem de linhas retornadas
- Contagem de linhas verificadas
- Contagem de bytes retornados
- Tempo de CPU da consulta
Para mais informações, consulte Métricas do Spanner.
Esquema de tabela
| Nome da coluna | Tipo | Descrição |
|---|---|---|
INTERVAL_END |
TIMESTAMP |
Fim do intervalo de tempo em que as execuções de consultas incluídas ocorreram. |
EXECUTION_COUNT |
INT64 |
Número de vezes que o Spanner viu a consulta durante o intervalo de tempo. |
AVG_LATENCY_SECONDS |
FLOAT64 |
Tempo médio, em segundos, para cada execução de consulta no banco de dados. Essa média exclui o tempo de codificação e transmissão do conjunto de resultados e também a sobrecarga. |
AVG_ROWS |
FLOAT64 |
Número médio de linhas que a consulta retornou. |
AVG_BYTES |
FLOAT64 |
Número médio de bytes de dados que a consulta retornou, excluindo a sobrecarga de codificação de transmissão. |
AVG_ROWS_SCANNED |
FLOAT64 |
Número médio de linhas que a consulta verificou, com exceção dos valores excluídos. |
AVG_CPU_SECONDS |
FLOAT64 |
Número médio de segundos de tempo de CPU que o Spanner gastou em todas as operações para executar a consulta. |
ALL_FAILED_EXECUTION_COUNT |
INT64 |
Número de vezes que a consulta falhou durante o intervalo. |
ALL_FAILED_AVG_LATENCY_SECONDS |
FLOAT64 |
Média de tempo, em segundos, para cada execução de consulta que falhou no banco de dados. Essa média exclui o tempo de codificação e transmissão do conjunto de resultados e também a sobrecarga. |
CANCELLED_OR_DISCONNECTED_EXECUTION_COUNT |
INT64 |
Número de vezes que a consulta foi cancelada pelo usuário ou falhou devido a uma falha na conexão de rede durante o intervalo. |
TIMED_OUT_EXECUTION_COUNT |
INT64 |
Número de vezes que a consulta expirou durante o intervalo. |
AVG_BYTES_WRITTEN |
FLOAT64 |
Número médio de bytes gravados pela instrução. |
AVG_ROWS_WRITTEN |
FLOAT64 |
Número médio de linhas modificadas pela instrução. |
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT |
INT64 |
O número de vezes que as consultas foram executadas como parte de transações de leitura e gravação. Essa coluna ajuda a determinar se é possível evitar conflitos de bloqueio movendo algumas consultas para transações somente leitura. |
LATENCY_DISTRIBUTION |
ARRAY<STRUCT> |
Um histograma do tempo de execução em todas as consultas. Os valores são medidos em segundos.
Especifique a matriz da seguinte maneira:
Para calcular a latência do percentil com base na distribuição,
use a função Para mais informações, consulte Percentis e métricas com valor de distribuição. |
LATENCY_DISTRIBUTION_JSON_STRING |
STRING |
Um histograma do tempo de execução da consulta. Os valores são medidos em segundos. Uma representação de string compatível com JSON da estatística
Essa coluna é compatível com bancos de dados de dialeto GoogleSQL e PostgreSQL. Essa coluna contém a Distribuição. Para calcular a latência do percentil com base na distribuição, use a função
Para mais informações, consulte Percentis e métricas com valor de distribuição. |
AVG_COLUMNAR_READ_SHARE |
FLOAT64 |
A porcentagem média de bytes lidos do armazenamento colunar em relação ao total de bytes lidos do armazenamento baseado em linhas e colunar, expressa como uma fração entre 0 e 1. Use essa estatística para monitorar o uso do mecanismo colunar em consultas. Para mais informações, consulte Monitorar o desempenho do mecanismo colunar. |
CPU_SECONDS_DISTRIBUTION |
ARRAY<STRUCT> |
Um histograma do tempo de CPU que o Spanner gastou em todas as operações para executar a consulta. Os valores são medidos em segundos.
A matriz tem a seguinte estrutura:
Para mais informações sobre os tipos de valor, consulte Distribuição e Exponencial. Para calcular os percentis de segundos de CPU com base na distribuição, use a função |
CPU_SECONDS_DISTRIBUTION_JSON_STRING |
STRING |
Uma representação de string compatível com JSON da estatística Essa coluna é compatível com bancos de dados de dialeto GoogleSQL e PostgreSQL. Para calcular os percentis de segundos de CPU da distribuição, use a função
|
ROW_SCANNED_DISTRIBUTION |
ARRAY<STRUCT> |
Um histograma do número de linhas verificadas pela consulta, excluindo os valores excluídos.
A matriz tem a seguinte estrutura:
Para mais informações sobre os tipos de valor, consulte Distribuição e Exponencial. Para calcular percentis de linhas verificadas na distribuição, use
a
função
|
ROW_SCANNED_DISTRIBUTION_JSON_STRING |
STRING |
Uma representação de string compatível com JSON da estatística Essa coluna é compatível com bancos de dados de dialeto GoogleSQL e PostgreSQL. Para calcular percentis de linhas verificadas na distribuição, use
a
função
|
Retenção de dados
No mínimo, o Spanner mantém os dados de cada tabela pelos seguintes períodos:
SPANNER_SYS.QUERY_STATS_TOP_MINUTEeSPANNER_SYS.QUERY_STATS_TOTAL_MINUTE: intervalos que abrangem as seis horas anteriores.SPANNER_SYS.QUERY_STATS_TOP_10MINUTEeSPANNER_SYS.QUERY_STATS_TOTAL_10MINUTE: intervalos abrangendo os quatro dias anteriores.SPANNER_SYS.QUERY_STATS_TOP_HOUReSPANNER_SYS.QUERY_STATS_TOTAL_HOUR: intervalos que abrangem os últimos 30 dias.
Exemplo de consultas
Nesta seção, há várias instruções SQL de exemplo que recuperam estatísticas de consulta. É possível executar essas instruções SQL usando as bibliotecas de cliente, a Google Cloud CLI ou o console doGoogle Cloud .
Listar as estatísticas básicas de cada consulta em um determinado período
A consulta a seguir retorna os dados brutos para as principais consultas no minuto anterior:
SELECT text,
request_tag,
interval_end,
execution_count,
avg_latency_seconds,
avg_rows,
avg_bytes,
avg_rows_scanned,
avg_cpu_seconds
FROM spanner_sys.query_stats_top_minute
ORDER BY interval_end DESC;
Listar as estatísticas de instruções DML particionadas que são executadas por mais de uma hora
A consulta a seguir retorna a contagem de execuções e a média de linhas gravadas pelas principais consultas DML particionadas nas horas anteriores:
SELECT text,
request_tag,
interval_end,
sum(execution_count) as execution_count,
sum(avg_rows_written*execution_count)/sum(execution_count) as avg_rows_written
FROM spanner_sys.query_stats_top_hour
WHERE starts_with(text, "UPDATE") AND query_type = "PARTITIONED_QUERY"
group by text, request_tag, interval_end
ORDER BY interval_end DESC;
Listar as consultas com o maior uso de CPU
A consulta a seguir retorna as consultas com o maior uso de CPU na hora anterior:
SELECT text,
request_tag,
execution_count AS count,
avg_latency_seconds AS latency,
avg_cpu_seconds AS cpu,
execution_count * avg_cpu_seconds AS total_cpu
FROM spanner_sys.query_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_hour)
ORDER BY total_cpu DESC;
Encontrar a contagem total de execuções em um determinado período
A consulta a seguir retorna o número total de consultas executadas no intervalo completo de 1 minuto mais recente:
SELECT interval_end,
execution_count
FROM spanner_sys.query_stats_total_minute
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_total_minute);
Encontrar a latência média de uma consulta
A consulta a seguir retorna as informações de latência média de uma consulta específica:
SELECT avg_latency_seconds
FROM spanner_sys.query_stats_top_hour
WHERE text LIKE "SELECT x FROM table WHERE x=@foo;";
Encontrar a latência do 99º percentil para consultas
Comparar a latência média com a latência do 99º percentil ajuda a identificar possíveis consultas atípicas com tempos de execução altos.
As consultas a seguir retornam o 99º percentil do tempo de execução em consultas executadas nos últimos 10 minutos.
Para bancos de dados de dialeto do GoogleSQL, use a coluna LATENCY_DISTRIBUTION:
SELECT interval_end, avg_latency_seconds, SPANNER_SYS.DISTRIBUTION_PERCENTILE(latency_distribution[OFFSET(0)], 99.0)
AS percentile_latency
FROM spanner_sys.query_stats_total_10minute
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_total_10minute)
ORDER BY interval_end;
Para bancos de dados de dialeto PostgreSQL, use a coluna LATENCY_DISTRIBUTION_JSON_STRING:
SELECT interval_end, avg_latency_seconds, SPANNER_SYS.DISTRIBUTION_PERCENTILE(latency_distribution_json_string, 99.0)
AS percentile_latency
FROM spanner_sys.query_stats_total_10minute
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_total_10minute)
ORDER BY interval_end;
Encontrar as consultas que verificam mais dados
É possível usar o número de linhas verificadas por uma consulta como uma medida da quantidade de dados que a consulta verificou. A consulta a seguir retorna o número de linhas verificadas por consultas executadas na hora anterior:
SELECT text,
execution_count,
avg_rows_scanned
FROM spanner_sys.query_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_hour)
ORDER BY avg_rows_scanned DESC;
Encontrar as instruções que gravaram mais dados
É possível usar o número de linhas gravadas (ou bytes gravados) pela DML como uma medida da quantidade de dados que a consulta modificou. A consulta a seguir retorna o número de linhas gravadas por instruções DML executadas na hora anterior:
SELECT text,
execution_count,
avg_rows_written
FROM spanner_sys.query_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_hour)
ORDER BY avg_rows_written DESC;
Uso total da CPU em todas as consultas
A consulta a seguir retorna o número de horas de CPU usadas na hora anterior:
SELECT (avg_cpu_seconds * execution_count / 60 / 60)
AS total_cpu_hours
FROM spanner_sys.query_stats_total_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_total_hour);
Listar as consultas que falharam em um determinado período
A consulta a seguir retorna os dados brutos, incluindo a contagem de execuções e a latência média das consultas com falha para as principais consultas no minuto anterior. Essas estatísticas não rastreiam instruções DML particionadas com falha e canceladas.
SELECT text,
request_tag,
interval_end,
execution_count,
all_failed_execution_count,
all_failed_avg_latency_seconds,
avg_latency_seconds,
avg_rows,
avg_bytes,
avg_rows_scanned,
avg_cpu_seconds
FROM spanner_sys.query_stats_top_minute
WHERE all_failed_execution_count > 0
ORDER BY interval_end;
Encontrar a contagem total de erros em um determinado período
A consulta a seguir retorna o número total de consultas que não foram executadas no intervalo completo mais recente de 1 minuto. Essas estatísticas não rastreiam instruções DML particionadas com falha e canceladas.
SELECT interval_end,
all_failed_execution_count
FROM spanner_sys.query_stats_total_minute
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_minute)
ORDER BY interval_end;
Listar as consultas que mais atingem o tempo limite
A consulta a seguir retorna as consultas com a contagem de tempo limite mais alta na hora anterior.
SELECT text,
execution_count AS count,
timed_out_execution_count AS timeout_count,
avg_latency_seconds AS latency,
avg_cpu_seconds AS cpu,
execution_count * avg_cpu_seconds AS total_cpu
FROM spanner_sys.query_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_hour)
ORDER BY timed_out_execution_count DESC;
Encontrar a latência média de execuções bem-sucedidas e com falha para uma consulta
A consulta a seguir retorna a latência média combinada, a latência média para execuções bem-sucedidas e a latência média para execuções com falha de uma consulta específica. Essas estatísticas não rastreiam instruções DML particionadas com falha e canceladas.
SELECT avg_latency_seconds AS combined_avg_latency,
all_failed_avg_latency_seconds AS failed_execution_latency,
( avg_latency_seconds * execution_count -
all_failed_avg_latency_seconds * all_failed_execution_count
) / (
execution_count - all_failed_execution_count ) AS success_execution_latency
FROM spanner_sys.query_stats_top_hour
WHERE text LIKE "select x from table where x=@foo;";
Resolver problemas de alto uso da CPU ou latência de consulta elevada com estatísticas de consulta
As estatísticas de consulta são úteis quando você precisa investigar o alto uso da CPU no banco de dados do Spanner ou quando está apenas tentando entender as formas de consulta com uso intensivo de CPU no banco de dados. Inspecionar consultas que usam quantidades significativas de recursos de banco de dados oferece aos usuários do Spanner uma maneira de reduzir os custos operacionais e possivelmente melhorar as latências gerais do sistema.
É possível usar o código SQL ou o painel do Query Insights para investigar consultas problemáticas no banco de dados. Os tópicos a seguir mostram como investigar essas consultas usando o código SQL.
Embora o exemplo a seguir se concentre no uso da CPU, é possível seguir etapas semelhantes para resolver problemas de latência de consulta elevada e encontrar as consultas com as maiores latências. Selecione intervalos de tempo e consultas por latência em vez de uso da CPU.
Selecione um período para investigar
Inicie a investigação procurando um horário em que o aplicativo começou a apresentar uso elevado da CPU. Por exemplo, se o problema começou a ocorrer por volta das 17h de 24 de julho de 2020 UTC.
Coletar estatísticas de consulta para o período selecionado
Depois de selecionar um período para iniciar a investigação, observe as estatísticas coletadas na tabela QUERY_STATS_TOTAL_10MINUTE nesse período.
Os resultados dessa consulta podem indicar como a CPU e outras estatísticas de consulta
mudaram durante esse período.
A consulta a seguir retorna as estatísticas de consulta agregadas de 16:30 a
17:30 UTC, inclusive. A consulta usa ROUND para restringir
o número de casas decimais para fins de exibição.
SELECT interval_end,
execution_count AS count,
ROUND(avg_latency_seconds,2) AS latency,
ROUND(avg_rows,2) AS rows_returned,
ROUND(avg_bytes,2) AS bytes,
ROUND(avg_rows_scanned,2) AS rows_scanned,
ROUND(avg_cpu_seconds,3) AS avg_cpu
FROM spanner_sys.query_stats_total_10minute
WHERE
interval_end >= "2020-07-24T16:30:00Z"
AND interval_end <= "2020-07-24T17:30:00Z"
ORDER BY interval_end;
A execução da consulta gerou os resultados a seguir.
| interval_end | contagem | latência | rows_returned | bytes | rows_scanned | avg_cpu |
|---|---|---|---|---|---|---|
| 2020-07-24T16:30:00Z | 6 | 0,06 | 5,00 | 536,00 | 16,67 | 0,035 |
| 2020-07-24T16:40:00Z | 55 | 0,02 | 0,22 | 25,29 | 0,22 | 0,004 |
| 2020-07-24T16:50:00Z | 102 | 0,02 | 0,30 | 33,35 | 0,30 | 0,004 |
2020-07-24T17:00:00Z |
154 |
1.06 |
4.42 |
486.33 |
7792208.12 |
4.633 |
| 2020-07-24T17:10:00Z | 94 | 0,02 | 1,68 | 106,84 | 1,68 | 0,006 |
| 2020-07-24T17:20:00Z | 110 | 0,02 | 0.38 | 34,60 | 0.38 | 0,005 |
| 2020-07-24T17:30:00Z | 47 | 0,02 | 0.23 | 24,96 | 0.23 | 0,004 |
Na tabela anterior, observe que o tempo médio de CPU, a coluna avg_cpu na tabela de resultados, é mais alto nos intervalos destacados que terminam às 17h. Além disso, observe um número muito maior de linhas verificadas em média. Isso indica que consultas mais caras foram executadas entre 16h50 e 17h. Escolha esse intervalo para investigar mais na próxima etapa.
Encontrar as consultas que estão causando alto uso da CPU
Com um intervalo de tempo para investigar selecionado, consulte a tabela QUERY_STATS_TOP_10MINUTE. Os resultados dessa consulta podem ajudar a indicar quais consultas causam alto uso de CPU.
SELECT text_fingerprint AS fingerprint,
execution_count AS count,
ROUND(avg_latency_seconds,2) AS latency,
ROUND(avg_cpu_seconds,3) AS cpu,
ROUND(execution_count * avg_cpu_seconds,3) AS total_cpu
FROM spanner_sys.query_stats_top_10minute
WHERE
interval_end = "2020-07-24T17:00:00Z"
ORDER BY total_cpu DESC;
A execução dessa consulta gera os seguintes resultados.
| Impressão digital | contagem | latência | cpu | total_cpu |
|---|---|---|---|---|
5505124206529314852 |
30 |
3.88 |
17.635 |
529.039 |
1697951036096498470 |
10 |
4.49 |
18.388 |
183.882 |
| 2295109096748351518 | 1 | 0,33 | 0,048 | 0,048 |
| 11618299167612903606 | 1 | 0,25 | 0,021 | 0,021 |
| 10302798842433860499 | 1 | 0,04 | 0,006 | 0,006 |
| 123771704548746223 | 1 | 0,04 | 0,006 | 0,006 |
| 4216063638051261350 | 1 | 0,04 | 0,006 | 0,006 |
| 3654744714919476398 | 1 | 0,04 | 0,006 | 0,006 |
| 2999453161628434990 | 1 | 0,04 | 0,006 | 0,006 |
| 823179738756093706 | 1 | 0,02 | 0,005 | 0,0056 |
As duas principais consultas, destacadas na tabela de resultados, são outliers em termos de CPU e latência média, bem como o número de execuções e o total de CPU. Investigue a primeira consulta listada nesses resultados.
Comparar execuções de consulta ao longo do tempo
Depois de restringir a investigação, verifique a tabela QUERY_STATS_TOP_MINUTE. Ao comparar as execuções ao longo do tempo para uma consulta específica, é possível procurar correlações entre o número de linhas ou bytes retornados ou o número de linhas verificadas e a CPU ou latência elevada. Um desvio pode indicar não uniformidade nos dados. Um número consistente de linhas
verificadas pode indicar a falta de índices apropriados ou uma ordem de mesclagem
não ideal.
Investigue a consulta que apresenta o maior uso médio de CPU e a maior latência executando a seguinte instrução, que filtra o text_fingerprint dessa consulta.
SELECT interval_end,
ROUND(avg_latency_seconds,2) AS latency,
avg_rows AS rows_returned,
avg_bytes AS bytes_returned,
avg_rows_scanned AS rows_scanned,
ROUND(avg_cpu_seconds,3) AS cpu,
FROM spanner_sys.query_stats_top_minute
WHERE text_fingerprint = 5505124206529314852
ORDER BY interval_end DESC;
Executar essa consulta retorna os seguintes resultados.
| interval_end | latência | rows_returned | bytes_retornados | rows_scanned | cpu |
|---|---|---|---|---|---|
| 2020-07-24T17:00:00Z | 4,55 | 21 | 2365 | 30000000 | 19,255 |
| 2020-07-24T16:00:00Z | 3,62 | 21 | 2365 | 30000000 | 17,255 |
| 2020-07-24T15:00:00Z | 4,37 | 21 | 2365 | 30000000 | 18,350 |
| 2020-07-24T14:00:00Z | 4,02 | 21 | 2365 | 30000000 | 17,748 |
| 2020-07-24T13:00:00Z | 3.12 | 21 | 2365 | 30000000 | 16,380 |
| 2020-07-24T12:00:00Z | 3,45 | 21 | 2365 | 30000000 | 15,476 |
| 2020-07-24T11:00:00Z | 4,94 | 21 | 2365 | 30000000 | 22,611 |
| 2020-07-24T10:00:00Z | 6,48 | 21 | 2365 | 30000000 | 21,265 |
| 2020-07-24T09:00:00Z | 0.23 | 21 | 2365 | 5 | 0,040 |
| 2020-07-24T08:00:00Z | 0,04 | 21 | 2365 | 5 | 0,021 |
| 2020-07-24T07:00:00Z | 0,09 | 21 | 2365 | 5 | 0.030 |
Ao analisar os resultados anteriores, observe que o número de linhas verificadas, a CPU usada e a latência mudaram significativamente por volta das 9h. Para entender por que esses números aumentaram tanto, analise o texto da consulta e veja se alguma alteração no esquema pode ter afetado a consulta.
Use a consulta a seguir para recuperar o texto da consulta que você está investigando.
SELECT text,
text_truncated
FROM spanner_sys.query_stats_top_hour
WHERE text_fingerprint = 5505124206529314852
LIMIT 1;
Isso retorna o resultado a seguir.
| text | text_truncated |
|---|---|
| Selecione * de pedidos em que o_custkey = 36901; | falso |
Ao examinar o texto da consulta retornada, observe que ela está
filtrando um campo chamado o_custkey. Esta é uma coluna não chave na tabela orders. Durante o processo, havia um índice nessa coluna que era solto por volta das 9h. Isso explica a mudança no custo dessa consulta. É possível adicionar
o índice novamente ou, se a consulta for executada com pouca frequência, decidir não ter o
índice e aceitar o custo de leitura mais alto.
Até agora, a investigação se concentrou em consultas que foram concluídas com sucesso e identificou um motivo para a degradação do desempenho do banco de dados. Na próxima etapa, concentre-se nas consultas com falha ou canceladas e examine esses dados para mais insights.
Investigar consultas com falha
As consultas que não são concluídas com sucesso ainda consomem recursos antes de expirar, serem canceladas ou falharem de outra forma. O Spanner rastreia a contagem de execuções e os recursos consumidos por consultas com falha, além das bem-sucedidas. Essas estatísticas não rastreiam instruções DML particionadas com falha e canceladas.
Para verificar se as consultas com falha contribuem significativamente para a utilização do sistema, primeiro verifique quantas consultas falharam no intervalo de tempo de interesse.
SELECT interval_end,
all_failed_execution_count AS failed_count,
all_failed_avg_latency_seconds AS latency
FROM spanner_sys.query_stats_total_minute
WHERE
interval_end >= "2020-07-24T16:50:00Z"
AND interval_end <= "2020-07-24T17:00:00Z"
ORDER BY interval_end;
| interval_end | failed_count | latência |
|---|---|---|
| 2020-07-24T16:52:00Z | 1 | 15,211391 |
| 2020-07-24T16:53:00Z | 3 | 58,312232 |
Para investigar mais, procure as consultas com maior probabilidade de falha usando a consulta a seguir.
SELECT interval_end,
text_fingerprint,
execution_count,
avg_latency_seconds AS avg_latency,
all_failed_execution_count AS failed_count,
all_failed_avg_latency_seconds AS failed_latency,
cancelled_or_disconnected_execution_count AS cancel_count,
timed_out_execution_count AS to_count
FROM spanner_sys.query_stats_top_minute
WHERE all_failed_execution_count > 0
ORDER BY interval_end;
| interval_end | text_fingerprint | execution_count | failed_count | cancel_count | to_count |
|---|---|---|---|---|---|
| 2020-07-24T16:52:00Z | 5505124206529314852 | 3 | 1 | 1 | 0 |
| 2020-07-24T16:53:00Z | 1697951036096498470 | 2 | 1 | 1 | 0 |
| 2020-07-24T16:53:00Z | 5505124206529314852 | 5 | 2 | 1 | 1 |
Como mostrado na tabela anterior, a consulta com impressão digital 5505124206529314852
falhou várias vezes em intervalos diferentes. Considerando um padrão de falhas como esse, é interessante comparar a latência de execuções bem-sucedidas e malsucedidas.
SELECT interval_end,
avg_latency_seconds AS combined_avg_latency,
all_failed_avg_latency_seconds AS failed_execution_latency,
( avg_latency_seconds * execution_count -
all_failed_avg_latency_seconds * all_failed_execution_count
) / (
execution_count - all_failed_execution_count ) AS success_execution_latency
FROM spanner_sys.query_stats_top_hour
WHERE text_fingerprint = 5505124206529314852;
| interval_end | combined_avg_latency | failed_execution_latency | success_execution_latency |
|---|---|---|---|
| 2020-07-24T17:00:00Z | 3,880420 | 13,830709 | 2,774832 |
Aplicar práticas recomendadas
Depois de identificar uma consulta candidata para otimização, analise o perfil de consulta e tente otimizar usando as práticas recomendadas de SQL.
A seguir
Use as consultas ativas mais antigas para determinar as consultas ativas mais longas.
Saiba mais sobre como investigar a alta utilização da CPU.
Saiba mais sobre outras ferramentas de introspecção.
Saiba mais sobre outras informações que o Spanner armazena para cada banco de dados nas tabelas de esquema de informações do banco de dados.
Saiba mais sobre as práticas recomendadas de SQL para o Spanner.