Usa optimizaciones basadas en el historial

En esta guía, se describe cómo funcionan las optimizaciones basadas en el historial y cómo estimar su impacto en las búsquedas.

Acerca de las optimizaciones basadas en el historial

Las optimizaciones basadas en el historial usan automáticamente información de ejecuciones ya completadas de consultas iguales o similares para aplicar optimizaciones adicionales y mejorar aún más el rendimiento de las consultas, como el tiempo de ranura consumido y la latencia de la consulta. Por ejemplo, la primera ejecución de la consulta puede tardar 60 segundos, pero la segunda ejecución de la consulta puede tardar solo 30 segundos si se identificó una optimización basada en el historial. Este proceso continúa hasta que no hay optimizaciones adicionales que agregar.

El siguiente es un ejemplo de cómo funcionan las optimizaciones basadas en el historial con BigQuery:

Cantidad de ejecuciones Tiempo de ranura de consulta consumido Notas
1 60 Ejecución original.
2 30 Se aplicó la primera optimización basada en el historial.
3 20 Se aplicó la segunda optimización basada en el historial.
4 21 No hay optimizaciones adicionales basadas en el historial que se apliquen.
5 19 No hay optimizaciones adicionales basadas en el historial que se apliquen.
6 20 No hay optimizaciones adicionales basadas en el historial que se apliquen.

Las optimizaciones basadas en el historial solo se aplican cuando se puede confiar en que habrá un impacto beneficioso en el rendimiento de las consultas. Además, cuando una optimización no mejora significativamente el rendimiento de las consultas o puede generar un rendimiento más bajo, esa optimización se revoca y no se usa en ejecuciones futuras de esa consulta.

Revisa las optimizaciones basadas en el historial de un trabajo

Para revisar las optimizaciones basadas en el historial de un trabajo, puedes usar una consulta de SQL o una llamada de método de la API de REST.

SQL

Puedes usar una consulta con el fin de obtener las optimizaciones basadas en el historial de un trabajo. La consulta debe incluir INFORMATION_SCHEMA.JOBS_BY_PROJECT y el nombre de la columna query_info.optimization_details.

En el siguiente ejemplo, los detalles de optimización se muestran para un trabajo llamado sample_job. Si no se aplicaron optimizaciones basadas en el historial, se produce NULL para optimization_details:

SELECT
  job_id,
  query_info.optimization_details
FROM `PROJECT_NAME.region-LOCATION`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE job_id = 'sample_job'
LIMIT 1;

Los resultados son similares a los siguientes:

-- The JSON in optimization_details has been formatted for readability.
/*------------+-----------------------------------------------------------------*
 | job_id     | optimization_details                                            |
 +------------+-----------------------------------------------------------------+
 | sample_job | {                                                               |
 |            |   "optimizations": [                                            |
 |            |     {                                                           |
 |            |       "semi_join_reduction": "web_sales.web_date,RIGHT"         |
 |            |     },                                                          |
 |            |     {                                                           |
 |            |       "semi_join_reduction": "catalog_sales.catalog_date,RIGHT" |
 |            |     },                                                          |
 |            |     {                                                           |
 |            |       "semi_join_reduction": "store_sales.store_date,RIGHT"     |
 |            |     },
 |            |     {                                                           |
 |            |       "join_commutation": "web_returns.web_item"                |
 |            |     },
 |            |     {                                                           |
 |            |       "parallelism_adjustment": "applied"                       |
 |            |     },
 |            |   ]                                                             |
 |            | }                                                               |
 *------------+-----------------------------------------------------------------*/

API

Para obtener los detalles de optimización de un trabajo, puedes llamar al método jobs.get.

En el siguiente ejemplo, el método jobs.get muestra los detalles de optimización (optimizationDetails) en la respuesta completa:

{
  "jobReference": {
    "projectId": "myProject",
    "jobId": "sample_job"
  }
}

Los resultados son similares a los siguientes:

-- The unrelated parts in the full response have been removed.
{
  "jobReference": {
    "projectId": "myProject",
    "jobId": "sample_job",
    "location": "US"
  },
  "statistics": {
    "query": {
      "queryInfo": {
        "optimizationDetails": {
          "optimizations": [
            {
              "semi_join_reduction": "web_sales.web_date,RIGHT"
            },
            {
              "semi_join_reduction": "catalog_sales.catalog_date,RIGHT"
            },
            {
              "semi_join_reduction": "store_sales.store_date,RIGHT"
            },
            {
              "join_commutation": "web_returns.web_item"
            },
            {
              "parallelism_adjustment": "applied"
            }
          ]
        }
      }
    }
  }
}

Estima el impacto de las optimizaciones basadas en el historial

Para estimar el impacto de las optimizaciones basadas en el historial, puedes usar la siguiente consulta en SQL de muestra para identificar las consultas del proyecto con la mayor mejora estimada en el tiempo de ejecución.

  WITH
    jobs AS (
      SELECT
        *,
        query_info.query_hashes.normalized_literals AS query_hash,
        TIMESTAMP_DIFF(end_time, start_time, MILLISECOND) AS elapsed_ms,
        IFNULL(
          ARRAY_LENGTH(JSON_QUERY_ARRAY(query_info.optimization_details.optimizations)) > 0,
          FALSE)
          AS has_history_based_optimization,
      FROM region-LOCATION.INFORMATION_SCHEMA.JOBS_BY_PROJECT
      WHERE EXTRACT(DATE FROM creation_time) > DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
    ),
    most_recent_jobs_without_history_based_optimizations AS (
      SELECT *
      FROM jobs
      WHERE NOT has_history_based_optimization
      QUALIFY ROW_NUMBER() OVER (PARTITION BY query_hash ORDER BY end_time DESC) = 1
    )
  SELECT
    job.job_id,
    100 * SAFE_DIVIDE(
      original_job.elapsed_ms - job.elapsed_ms,
      original_job.elapsed_ms) AS percent_execution_time_saved,
    job.elapsed_ms AS new_elapsed_ms,
    original_job.elapsed_ms AS original_elapsed_ms,
  FROM jobs AS job
  INNER JOIN most_recent_jobs_without_history_based_optimizations AS original_job
    USING (query_hash)
  WHERE
    job.has_history_based_optimization
    AND original_job.end_time < job.start_time
  ORDER BY percent_execution_time_saved DESC
  LIMIT 10;

El resultado de la consulta anterior es similar al siguiente si se aplicaron optimizaciones basadas en el historial:

  /*--------------+------------------------------+------------------+-----------------------*
   |    job_id    | percent_execution_time_saved | new_execution_ms | original_execution_ms |
   +--------------+------------------------------+------------------+-----------------------+
   | sample_job1  |           67.806850186245114 |             7087 |                 22014 |
   | sample_job2  |           66.485800412501987 |            10562 |                 31515 |
   | sample_job3  |           63.285605271764254 |            97668 |                266021 |
   | sample_job4  |           61.134141726887904 |           923384 |               2375823 |
   | sample_job5  |           55.381272089713754 |          1060062 |               2375823 |
   | sample_job6  |           45.396943168036479 |          2324071 |               4256302 |
   | sample_job7  |           38.227031526376024 |            17811 |                 28833 |
   | sample_job8  |           33.826608962725111 |            66360 |                100282 |
   | sample_job9  |           32.087813758311604 |            44020 |                 64819 |
   | sample_job10 |           28.356416319483539 |            19088 |                 26643 |
   *--------------+------------------------------+------------------+-----------------------*/

Los resultados de esta consulta son solo una estimación del impacto de las optimizaciones basadas en el historial. Muchos factores pueden influir en el rendimiento de las consultas, incluidos, sin limitaciones, la disponibilidad de los espacios, el cambio en los datos a lo largo del tiempo, las definiciones de vistas o UDF, y las diferencias en los valores de los parámetros de consulta.

Si el resultado de esta consulta de muestra está vacío, significa que ninguna tarea usó las optimizaciones basadas en el historial o que todas las consultas se optimizaron hace más de 30 días.

Esta consulta se puede aplicar a otras métricas de rendimiento de consultas, como total_slot_ms y total_bytes_billed. Para obtener más información, consulta el esquema de INFORMATION_SCHEMA.JOBS.