SELECTSELECT

SELECT

Query tags de Snowflake para un monitoreo más preciso

By Ian WhitestoneFeb 7, 20237 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

Los query tags de Snowflake te permiten asociar metadatos arbitrarios a cada consulta. En este post te mostramos cómo usarlos para ganar visibilidad y monitorear mejor los costos y el rendimiento de tus consultas en Snowflake.

¿Qué es un query tag en Snowflake?

Los query tags son un parámetro opcional a nivel de sesión que permite etiquetar cualquier sentencia SQL de Snowflake con una cadena de texto. Pueden tener hasta 2000 caracteres y admitir cualquier carácter. El valor del query tag de cada consulta aparece en la salida de las vistas query_history de Snowflake, lo que abre la puerta a distintos casos de uso.

Vale la pena aclarar que los query tags no son lo mismo que los object tags. Ambos comparten el objetivo de aportar un monitoreo más estructurado y mejorar la visibilidad dentro de tu cuenta de Snowflake. Sin embargo, los object tags se aplican a objetos persistentes de la cuenta, como usuarios, roles, tablas, vistas, funciones y más.

¿Por qué conviene usar query tags en Snowflake?

Para la mayoría de los usuarios de Snowflake, los costos de cómputo de las consultas que se ejecutan en virtual warehouses representan la mayor parte del gasto en Snowflake. Si bien se puede atribuir el gasto de cómputo de un warehouse a distintos usuarios calculando el costo por consulta, muchas veces ese nivel de granularidad se queda corto, ya que una sola cuenta de usuario de producción puede concentrar la mayor parte de las consultas y de los costos.

Los query tags permiten una atribución de costos mucho más fina. Si tienes una sentencia SQL, o una serie de sentencias SQL asociadas a un modelo de datos dentro de un pipeline, puedes asignarles el mismo query tag. Así, los costos se atribuyen fácilmente a todas las consultas que compartan esa etiqueta. La alternativa pasa por agrupar por query_text, lo cual no permite reunir varias sentencias SQL relacionadas. Además, deja de funcionar cuando el texto SQL de un modelo de datos cambia, algo que tarde o temprano sucede.

Los query tags también sirven para monitorear el rendimiento de las consultas con mayor granularidad. Siguiendo con el ejemplo anterior, quizás quieras controlar el tiempo total de ejecución de cada modelo de datos sumando el tiempo transcurrido de todas las consultas asociadas. O bien, si un conjunto de consultas alimenta dashboards de aplicaciones para usuarios finales, los query tags te dan un monitoreo de rendimiento más focalizado.

Por último, los query tags permiten vincular las consultas con metadatos de otros sistemas. Un query tag podría incluir un dashboard_id, lo que te permitiría agregar todos los costos de un mismo dashboard y luego ver con qué frecuencia se usa a partir de los metadatos de la herramienta de BI.

¿Cómo se usan los query tags en Snowflake?

Definir tags por defecto

Los query tags son un parámetro a nivel de sesión, pero se pueden establecer valores por defecto a nivel de cuenta y de usuario. Por ejemplo:

1alter user shauna set query_tag = '{"team": "engineering", "user": "shauna"}';

A partir de ese momento, todas las consultas que ejecute este usuario llevarán este tag por defecto.

Definir query tags a nivel de sesión

Usa el comando alter session para establecer el query tag. Tras ejecutarlo, todas las consultas posteriores de la misma sesión quedarán etiquetadas con esa cadena.

alter session set query_tag='users_model';

-- this query will be tagged with 'users_model'
create or replace table users_tmp as (
  select *
  from raw_users
  where
    not deleted
    and created_at > current_date - 1
);

-- this will also be tagged with 'users_model'
insert into users
from users_tmp
;

Expandir código

Recomendamos usar los valores por defecto del usuario siempre que sea posible, para evitar llamadas frecuentes a alter session que sumen latencia a la ejecución de las consultas.

Definir query tags en Python

Si usas Python para ejecutar consultas, hay dos formas de establecer query tags.

Configurarlo una sola vez al crear la conexión

Al crear tu objeto de conexión con el Snowflake Python Connector, puedes definir los parámetros de sesión desde el inicio. En el ejemplo a continuación, todas las consultas ejecutadas desde este objeto con quedarán etiquetadas con DATA_MODELLING_PIPELINE.

con = snowflake.connector.connect(
    user='XXXX',
    password='XXXX',
    account='XXXX',
    session_parameters={
        'QUERY_TAG': 'DATA_MODELLING_PIPELINE',
    }
)

Modificarlo manualmente con alter session

Si no quieres que todas las consultas de tu sesión compartan el mismo tag, puedes ejecutar alter session set query_tag = 'XXX' antes de lanzar tus consultas.

con.cursor().execute("alter session set query_tag='users_model'")

query = """
create or replace table users_tmp as (
  select *
  from raw_users
  where
    not deleted
    and created_at > current_date - 1
)
"""

con.cursor().execute(query) # tagged with 'users_model'
con.cursor().execute("insert into users from users_tmp") # tagged with 'users_model'

Expandir código

Definir query tags en dbt

Si usas dbt, tienes tres opciones para definir query tags:

  1. Se pueden definir una sola vez en tu profiles.yml (fuente). Todas las consultas que se ejecuten en tu proyecto de dbt quedarán etiquetadas con ese valor.
  2. Los tags se pueden aplicar a todos los modelos bajo un resource_path concreto, o a un solo modelo, añadiendo un +query_tag en tu dbt_project.yml. Para modelos individuales, también puedes indicar el query tag en la config del modelo, es decir, {{ config(query_tag = 'XXX') }}. Si se ha definido un query tag por defecto en profiles.yml, cualquiera de estos tags más específicos lo sobrescribirá.
  3. Puedes crear un macro set_query_tag que asigne automáticamente el nombre del modelo como query tag para todos los modelos de tu proyecto.

Consulta la documentación de dbt para ver ejemplos de cada opción, y ten presente el posible modo de falla que mencionan: ante ciertos errores aguas arriba, las consultas pueden quedar con un tag incorrecto.

Hace poco publicamos un nuevo paquete de dbt, dbt-snowflake-query-tags, para etiquetar todas las consultas que emite dbt con un conjunto completo de metadatos. Échale un vistazo.

Usar cadenas JSON

Al definir query tags, recomendamos usar un objeto JSON por practicidad y consistencia. Siguiendo con el ejemplo anterior del etiquetado de modelos de datos, podríamos usar un objeto JSON para sumar información adicional como el entorno en el que se ejecutó el modelo, la versión, el disparador de la ejecución (¿fue programada o se invocó manualmente?), entre otros.

import json

query_tag = {
  'app_name': 'pipeline',
  'model_name': 'users',
  'environment': 'prod',
  'version': 'v1.2',
  'trigger': 'schedule'
}
con.cursor().execute(f"alter session set query_tag='{json.dumps(query_tag)}'")

con.cursor().execute(model_sql)

Cómo usar los query tags para monitorear costos y rendimiento en Snowflake

Los query tags aparecen en las vistas de query history para cada query_id. Aquí tienes un ejemplo de consulta que muestra el rendimiento promedio por query_tag:

Si el query_tag contiene un objeto JSON, se puede parsear y segmentar por cualquiera de sus claves. Retomando el ejemplo anterior:

select
    query_tag,
    count(*) as num_executions,
    avg(total_elapsed_time/1000) as avg_total_elapsed_time_s
from snowflake.account_usage.query_history
where
    start_time > current_date - 7
group by 1

Usar el paquete dbt-snowflake-monitoring

Si usas el paquete de dbt de SELECT para monitorear costos y rendimiento, puedes analizar tanto el costo como el rendimiento por query tag:

select
    try_parse_json(query_tag)['model_name']::string as model_name,
    count(*) as num_executions,
    avg(total_elapsed_time/1000) as avg_total_elapsed_time_s
from snowflake.account_usage.query_history
where
    try_parse_json(query_tag)['app_name']::string = 'pipeline'
    and start_time > current_date - 7
group by 1

Además notarás que estas consultas se ejecutan mucho más rápido que una consulta contra las vistas de account usage de Snowflake, ya que la tabla está materializada y ordenada por start_time para lograr un buen clustering.

Usar comentarios en las consultas en lugar de query tags

Otra práctica habitual para etiquetar consultas es agregar un comentario al final 1 de cada una:

select
    try_parse_json(query_tag)['model_name']::string as model_name,
    count(*) as num_executions,
    sum(query_cost) as total_cost,
    avg(total_elapsed_time_s) as avg_total_elapsed_time_s
from query_history_enriched
where
    try_parse_json(query_tag)['app_name']::string = 'pipeline'
    and start_time > current_date - 7
group by 1

Esto tiene la ventaja de aplicarse a cualquier data warehouse y es más fácil de implementar, ya que no requiere ejecutar una sentencia alter session. Otra ventaja interesante es el rendimiento: ejecutar un alter session implica una llamada de red de ida y vuelta a Snowflake 2. Para la mayoría de los casos esto no supone problema, pero puede no ser aceptable en aplicaciones donde sumar 100-200 ms al tiempo de respuesta sí pesa. Por último, dado que el texto de la consulta puede llegar a 1 MB, los comentarios pueden contener muchos más metadatos que los query tags, limitados a 2000 caracteres.

Siempre que sea posible, recomendamos usar query tags, ya que son mucho más simples de parsear y analizar después. Si tus metadatos pueden superar los 2000 caracteres, quédate con los comentarios.

Notas

  1. Snowflake elimina automáticamente cualquier comentario al inicio de cada consulta, así que tienes que añadirlos al final.

  2. La sentencia alter session en sí es extremadamente rápida: tarda unos 30 ms en promedio.

Ian Whitestone·Co-founder & CEO de SELECT

Ian es Co-founder & CEO de SELECT, una plataforma SaaS de gestión y optimización de costos de Snowflake. Antes de fundar SELECT, Ian pasó 6 años liderando equipos full stack de data science e ingeniería en Shopify y Capital One. En Shopify, lideró los esfuerzos para optimizar su data warehouse y mejorar la observabilidad de costos.