Cómo solucionar problemas de regresiones de rendimiento

Cuando usas consultas de SQL para buscar datos, Spanner usa de forma automática cualquier índice secundario que puede ayudar a recuperar los datos de manera más eficiente. Sin embargo, en algunos casos, Spanner podría elegir un índice que haga que las consultas sean más lentas. Como resultado, podrías notar que algunas consultas se ejecutan de forma más lenta que en el pasado.

En esta página, se explica cómo detectar cambios en la velocidad de ejecución de las consultas, inspeccionar el plan de ejecución de esas consultas y especificar un índice diferente para consultas futuras si es necesario.

Detecta cambios en la velocidad de ejecución de las consultas

Es muy probable que veas un cambio en la velocidad de ejecución de las consultas después de realizar alguno de estos cambios:

  • Cambiar de forma significativa una gran cantidad de datos existentes que tienen un índice secundario.
  • Agregar, cambiar o descartar un índice secundario.

Puedes usar varias herramientas diferentes para identificar una consulta específica que Spanner ejecuta de forma más lenta de lo habitual:

Nota sobre las bases de datos nuevas

Cuando se consultan bases de datos recién creadas con datos recién insertados o importados, es posible que Spanner no seleccione los índices más adecuados, ya que el optimizador de consultas tarda hasta tres días en recopilar las estadísticas del optimizador de forma automática. Para optimizar el uso del índice de una base de datos de Spanner nueva antes que eso, puedes crear de forma manual un nuevo paquete de estadísticas.

Revisa el esquema

Después de encontrar la consulta lenta, observa la instrucción de SQL para la consulta y, luego, identifica las tablas que usa la instrucción y las columnas que recupera de esas tablas.

A continuación, busca los índices secundarios que existen para esas tablas. Determina si alguno de los índices incluye las columnas que consultas, lo que significa que Spanner podría usar uno de los índices para procesar la consulta.

  • Si hay índices aplicables, el siguiente paso es encontrar el índice que Spanner usó para la consulta.
  • Si no hay índices aplicables, usa el comando gcloud spanner operations list para verificar si de forma reciente descartaste un índice aplicable:

    gcloud spanner operations list \
        --instance=INSTANCE \
        --database=DATABASE \
        --filter="@TYPE:UpdateDatabaseDdlMetadata"
    

    Si descartaste un índice aplicable, el cambio tal vez afectó el rendimiento de la consulta. Vuelve a agregar el índice secundario a la tabla. Después de que Spanner agregue el índice, vuelve a ejecutar la consulta y observa su rendimiento. Si el rendimiento no mejora, el siguiente paso es encontrar el índice que Spanner usó para la consulta.

    Si no descartaste un índice aplicable, entonces la selección del índice no hizo que el rendimiento de la consulta empeorara. Busca otros cambios en tus datos o patrones de uso que podrían haber afectado el rendimiento.

Encuentra el índice que se usó para una consulta

Si deseas saber qué índice usa Spanner para procesar una consulta, visualiza el plan de ejecución de consultas en la consola de Google Cloud:

  1. Ve a la página Instancias de Spanner en la consola de Google Cloud.

    Ir a la página Instancias

  2. Haz clic sobre el nombre de la instancia que deseas consultar.

  3. En el panel izquierdo, haz clic en la base de datos que deseas consultar y, luego, en Spanner Studio.

  4. Ingresa la consulta que deseas probar.

  5. En la lista desplegable Ejecutar consulta, selecciona Solo explicación. Spanner muestra el plan de consultas.

Busca al menos uno de los operadores siguientes en el plan de consultas:

  • Análisis de tabla
  • Análisis del índice
  • Aplicación cruzada o aplicación distribuida cruzada

En las siguientes secciones, se explica el significado de cada operador.

Operador de análisis de tabla

El operador de análisis de tablas indica que Spanner no usó un índice secundario:

Una captura de pantalla muestra un operador de análisis de tabla en un plan de consultas.

Por ejemplo, supongamos que la tabla Albums no tiene ningún índice secundario y ejecutas la consulta siguiente:

SELECT AlbumTitle FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

Debido a que no hay índices para usar, el plan de consultas incluye un operador de análisis de tabla.

Operador de análisis del índice

El operador de análisis del índice indica que Spanner usó un índice secundario cuando procesó la consulta:

Una captura de pantalla muestra un operador de análisis del índice en un plan de consultas.

Por ejemplo, supongamos que agregas un índice a la tabla Albums:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

Luego, ejecuta la consulta siguiente:

SELECT AlbumTitle FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

El índice AlbumsByAlbumTitle contiene AlbumTitle, que es la única columna que selecciona la consulta. Como resultado, el plan de consultas incluye un operador de análisis del índice.

Operador de aplicación cruzada

En algunos casos, Spanner usa un índice que contiene solo algunas de las columnas que selecciona la consulta. Como resultado, Spanner debe unir el índice con la tabla base.

Cuando se produce este tipo de unión, el plan de consultas incluye un operador de aplicación cruzada o de aplicación distribuida cruzada que tiene las siguientes entradas:

  • Un operador de análisis del índice para el índice de una tabla
  • Un operador de análisis de tabla para la tabla que posee el índice

Una captura de pantalla muestra una aplicación distribuida cruzada en un plan de consultas, con un análisis del índice y un análisis de tabla como entradas.

Por ejemplo, supongamos que agregas un índice a la tabla Albums:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

Luego, ejecuta la consulta siguiente:

SELECT * FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

El índice AlbumsByAlbumTitle contiene AlbumTitle, pero la consulta selecciona todas las columnas de la tabla, no solo AlbumTitle. Como resultado, el plan de consultas incluye un operador de aplicación distribuida cruzada, con un análisis del índice de AlbumsByAlbumTitle y un análisis de tabla de Albums como sus entradas.

Elige un índice diferente

Después de encontrar el índice que Spanner usó para tu consulta, intenta ejecutar la consulta con un índice diferente o mediante el análisis de la tabla base en lugar de usar un índice. Para especificar el índice, agrega una directiva FORCE_INDEX a la consulta.

Si encuentras una versión más rápida de la consulta, actualiza tu aplicación para usar esa versión.

Lineamientos para elegir un índice

Usa estos lineamientos a fin de decidir qué índice probar para la consulta:

  • Si tu consulta cumple con alguno de estos criterios, intenta usar la tabla base en lugar de un índice secundario:

    • La consulta verifica la igualdad con un prefijo de la clave primaria de la tabla base (por ejemplo, SELECT * FROM Albums WHERE SingerId = 1).
    • Una gran cantidad de filas satisfacen los predicados de consulta (por ejemplo, SELECT * FROM Albums WHERE AlbumTitle != "There Is No Album With This Title").
    • La consulta usa una tabla base que contiene solo cientos de filas.
  • Si la consulta contiene un predicado muy selectivo (por ejemplo, REGEXP_CONTAINS, STARTS_WITH, <, <=, >, >= o !=), intenta con un índice que incluya las mismas columnas que usas en el predicado.

Prueba la consulta actualizada

Usa la consola de Google Cloud para probar la consulta actualizada y averiguar cuánto tiempo se tarda en procesarla.

Si tu consulta incluye parámetros de consulta y uno de ellos está vinculado a algunos valores mucho más que otros, vincula el parámetro de consulta a uno de esos valores en tus pruebas. Por ejemplo, si la consulta incluye un predicado como WHERE country = @countryId y casi todas tus consultas vinculan @countryId al valor US, entonces vincula @countryId a US para tus pruebas de rendimiento. Con este enfoque, optimizas las consultas que ejecutas con más frecuencia.

Para probar la consulta actualizada en la consola de Google Cloud, sigue estos pasos:

  1. Ve a la página Instancias de Spanner en la consola de Google Cloud.

    Ir a la página Instancias

  2. Haz clic sobre el nombre de la instancia que deseas consultar.

  3. En el panel izquierdo, haz clic en la base de datos que deseas consultar y, luego, en Spanner Studio.

  4. Ingresa la consulta que deseas probar, incluida la directiva FORCE_INDEX, y haz clic en Ejecutar consulta.

    La consola de Google Cloud abre la pestaña Tabla de resultados y, luego, muestra los resultados de la consulta, incluido el tiempo que tardó el servicio de Spanner en procesar la consulta.

    Esta métrica no incluye otras fuentes de latencia, como el tiempo que tardó la consola de Google Cloud en interpretar y mostrar los resultados de la consulta.

Obtén el perfil detallado de una consulta en formato JSON con la API de REST

De forma predeterminada, solo se muestran los resultados de las instrucciones cuando ejecutas una consulta. Esto se debe a que QueryMode está establecido en NORMAL. Para incluir estadísticas de ejecución detalladas con los resultados de la consulta, establece QueryMode en PROFILE.

Crea una sesión

Antes de actualizar el modo de consulta, crea una sesión, que representa un canal de comunicación con el servicio de base de datos de Spanner.

  1. Haz clic en projects.instances.databases.sessions.create.
  2. Proporciona el ID de proyecto, de la instancia y de la base de datos con el siguiente formato:

    projects/[\PROJECT_ID\]/instances/[\INSTANCE_ID\]/databases/[\DATABASE_ID\]
    
  3. Haz clic en Ejecutar. La respuesta muestra la sesión que creaste con este formato:

    projects/[\PROJECT_ID\]/instances/[\INSTANCE_ID\]/databases/[\DATABASE_ID\]/sessions/[\SESSION\]
    

    La usarás para realizar el perfil de la consulta en el paso siguiente. La sesión creada estará activa durante al menos una hora entre usos consecutivos antes de que la base de datos la borre.

Crea un perfil de la consulta

Habilita el modo PROFILE para la consulta.

  1. Haz clic en projects.instances.databases.sessions.executeSql.
  2. Para la sesión, ingresa el ID de sesión que creaste en el paso anterior:

    projects/[PROJECT_ID]/instances/[INSTANCE_ID]/databases/[DATABASE_ID]/sessions/[SESSION]
    
  3. En el cuerpo de la solicitud, usa lo siguiente:

    {
      "sql": "[YOUR_SQL_QUERY]",
      "queryMode": "PROFILE"
    }
    
  4. Haz clic en Ejecutar. La respuesta mostrada incluirá los resultados de la consulta, el plan de consultas y las estadísticas de ejecución de la consulta.