O Couchbase Analytics foi projetado para oferecer suporte a consultas ad hoc, aproveitando o processamento paralelo eficiente. Isso é particularmente útil quando os resultados de uma consulta o levam a buscar respostas em outra consulta. (Para os analistas, em outras palavras, o tempo todo!) Como em qualquer plataforma de dados, essas consultas secundárias podem, às vezes, resultar em tempos de execução significativamente diferentes dos da primeira. Recentemente, trabalhamos com um cliente que observou uma queda perceptível no desempenho depois de fazer uma pequena alteração em sua consulta. O processo pelo qual passamos para isolar e resolver o problema está descrito abaixo.

Os dados

Como sempre, a primeira etapa para entender uma consulta é se familiarizar com os dados subjacentes. Nesse caso, os dados são compostos de documentos JSON, cada um dos quais é uma descrição das cobranças do cliente por serviços. As cobranças de cada sessão são incorporadas em uma matriz:

Algumas observações sobre o design do modelo de dados:

  • Eles foram inteligentes com relação aos nomes dos campos, que são longos o suficiente para serem descritivos, mas curtos o suficiente para economizar espaço. Os nomes de campo dentro da matriz poderiam facilmente ter sido escritos como "quantity", "revenueCode", "service", "amount", "serviceDate". Em 100 milhões de instâncias, no entanto, isso exigiria um adicional de 3,73 GB de espaço antes da compactação.
  • Eles usaram datas de época, sem milissegundos. Se essas datas fossem armazenadas no formato ISO 8601 ("2020-07- 24T18:17:49" ou com milissegundos "2020-07-24T18:17:49.000"), elas exigiriam o dobro do espaço de armazenamento.

Consulta inicial

A consulta inicial foi projetada para recuperar a combinação de cliente/serviço de maior receita em cada uma das categorias de código de receita:

Algumas observações sobre o design da consulta:

  • O conteúdo da matriz é acessado pelo verbo "unnest". Isso permite que os valores sejam agregados e retornados como um registro nivelado.
  • A data de serviço mais recente é convertida de época para data legível por humanos por meio da função millis_to_str().
  • A função de janela "rank() over partition" é usada na cláusula where da consulta externa como um meio eficiente de retornar apenas o valor superior em cada código de receita.
  • A função round() é cosmética, mas comumente usada em relatórios em que os centavos não são significativos.

A desaceleração

Os problemas surgiram quando foi adicionado um cálculo de desconto por volume (20% off quando a quantidade acumulada de um serviço é 10 ou mais). Essa nova consulta levou seis vezes mais tempo para ser executada!

Como podemos rastrear a causa disso?

Explique-se

O console de consulta do Analytics facilita a inspeção do plano de execução de qualquer consulta, bastando clicar no botão "Plan" (Plano). A Figura (1) abaixo mostra o plano de consulta para essa consulta. Não se preocupe com a escala minúscula do diagrama; você pode usar os controles para expandi-lo e contraí-lo. Você também pode clicar em cada etapa individual para obter informações detalhadas.

Figure 1

Figura 1

Se preferir, você também pode clicar no botão "Plan Text" (Texto do plano) para gerar um documento JSON descrevendo o plano:

 

Isso pode se tornar muito aninhado (e um pouco difícil de ler) à medida que as consultas se tornam mais complexas. Um truque que nossos engenheiros costumam usar é anexar o comando "explain text" (explicar texto) na frente da consulta:

Isso fornece uma descrição detalhada do plano sem os colchetes ondulados:

Isso é o que usaremos para procurar pistas.

Vamos fazer uma lista

Temos quase certeza de que a lentidão foi introduzida quando adicionamos a instrução CASE que define o campo adjDollars, portanto, vamos começar procurando a lógica de caso. Nós a encontramos na linha 33:

Ao seguirmos a lógica nas linhas seguintes, vemos que o plano de execução continua a atribuir e trocar variáveis de forma particionada. Na linha 44, entretanto, vemos o seguinte:

Nos casos em que o desempenho da consulta ou o consumo de memória são uma preocupação, a função "listify" pode ser um sinal de alerta. (Ela tem seu uso, principalmente na transformação interna de agregados de matriz, mas também pode ser usada pelo plano de execução como a função de último recurso. No nosso caso, vemos que a variável $$117 é o resultado desse processo de listify. Essa $$117, como podemos ver no caso de troca acima, está associada ao objeto sum(c.amt) na consulta. Portanto, vamos tentar mover o cálculo das somas para fora do caso de troca interior e torná-las parte de um LET:

Depois de fazermos isso e reexaminarmos o plano de explicação, vemos que seu comprimento foi reduzido pela metade e que o processo de execução não inclui mais as funções listify. A execução da consulta, então, deve mostrar um desempenho muito melhor, o que de fato acontece. Problema resolvido!

Uma observação final: nossos engenheiros estão sempre procurando maneiras de melhorar nosso otimizador de consultas. Se, durante a otimização de uma de suas consultas, você encontrar no texto explicativo uma função "listify" desonesta (o que já é raro e está ficando cada vez mais raro), abra um tíquete de suporte em support.couchbase.com, carregando seu plano explicativo para que eles possam dar uma olhada nele. Na verdade, como resultado direto do trabalho com o cliente mencionado acima, esse exemplo específico (switch-case usado com uma função agregada) será, a partir da versão 6.6 do Couchbase, automaticamente reescrito pelo otimizador.

Documentos e recursos

O site de documentos do Couchbase contém links para a referência da linguagem N1QL for Analytics: https://docs.couchbase.com/server/current/analytics/introduction.html. Lá você também encontra um link para um tutorial sobre a linguagem e para o livro de Don Chamberlin (co-inventor da linguagem SQL): https://www.couchbase.com/sql-plus-plus-for-sql-users.

 

Muito obrigado a Dmitry Lychagin e Mike Carey pela revisão cuidadosa desta publicação.

 

Autor

Postado por Peter Reale

Peter Reale é engenheiro de soluções sênior da Couchbase e atua no setor de dados desde 1984. Ele mora em Los Angeles.

Deixar uma resposta