Verlaufsbasierte Optimierungen verwenden
In diesem Leitfaden wird beschrieben, wie verlaufsbasierte Optimierungen funktionieren und wie Sie ihre Auswirkungen auf Abfragen schätzen können.
Verlaufsbasierte Optimierungen
Verlaufsbasierte Optimierungen verwenden automatisch Informationen aus bereits abgeschlossenen Ausführungen derselben oder ähnlicher Abfragen, um zusätzliche Optimierungen anzuwenden und die Abfrageleistung, z. B. verbrauchte Slot-Zeit und Abfragelatenz, weiter zu verbessern. Die erste Abfrageausführung kann beispielsweise 60 Sekunden dauern, die zweite Ausführung jedoch nur 30 Sekunden, wenn eine verlaufsbasierte Optimierung ermittelt wurde. Dieser Vorgang wird fortgesetzt, bis keine weiteren Optimierungen mehr hinzugefügt werden können.
Im Folgenden finden Sie ein Beispiel für die Funktionsweise verlaufsbasierter Optimierungen mit BigQuery:
| Ausführungsanzahl | Genutzte Slot-Zeit für Abfrage | Hinweise |
|---|---|---|
| 1 | 60 | Ursprüngliche Ausführung. |
| 2 | 30 | Erste verlaufsbasierte Optimierung angewendet. |
| 3 | 20 | Zweite verlaufsbasierte Optimierung angewendet. |
| 4 | 21 | Es können keine weiteren verlaufsbasierten Optimierungen angewendet werden. |
| 5 | 19 | Es können keine weiteren verlaufsbasierten Optimierungen angewendet werden. |
| 6 | 20 | Es können keine weiteren verlaufsbasierten Optimierungen angewendet werden. |
Verlaufsbasierte Optimierungen werden nur angewendet, wenn es wahrscheinlich ist, dass sich die Abfrageleistung vorteilhaft auf die Abfrageleistung auswirkt. Wenn eine Optimierung die Abfrageleistung nicht erheblich verbessert oder zu einer schlechteren Leistung führen kann, wird sie widerrufen und nicht bei zukünftigen Ausführungen dieser Abfrage verwendet.
Verlaufsbasierte Optimierungen für einen Job prüfen
Sie können eine SQL-Abfrage oder einen REST API-Methodenaufruf verwenden, um die verlaufsbasierten Optimierungen für einen Job zu prüfen.
SQL
Sie können eine Abfrage verwenden, um die verlaufsbasierten Optimierungen für einen Job abzurufen.
Die Abfrage muss INFORMATION_SCHEMA.JOBS_BY_PROJECT und den Spaltennamen query_info.optimization_details enthalten.
Im folgenden Beispiel werden die Optimierungsdetails für einen Job namens sample_job zurückgegeben. Wenn keine verlaufsbasierten Optimierungen angewendet wurden, wird NULL für optimization_details erstellt:
SELECT
job_id,
query_info.optimization_details
FROM `PROJECT_NAME.region-LOCATION`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE job_id = 'sample_job'
LIMIT 1;
Die Ergebnisse sehen in etwa so aus:
-- 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
Rufen Sie die Methode jobs.get auf, um die Optimierungsdetails für einen Job abzurufen.
Im folgenden Beispiel gibt die Methode jobs.get die Optimierungsdetails (optimizationDetails) in der vollständigen Antwort zurück:
{
"jobReference": {
"projectId": "myProject",
"jobId": "sample_job"
}
}
Die Ergebnisse sehen in etwa so aus:
-- 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"
}
]
}
}
}
}
}
Auswirkungen verlaufsbasierter Optimierungen schätzen
Um die Auswirkungen verlaufsbasierter Optimierungen zu schätzen, können Sie die folgende SQL-Abfrage verwenden, um Projektanfragen mit der größten geschätzten Verbesserung der Ausführungszeit zu ermitteln.
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;
Das Ergebnis der vorherigen Abfrage sieht in etwa so aus, wenn verlaufsbasierte Optimierungen angewendet wurden:
/*--------------+------------------------------+------------------+-----------------------*
| 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 |
*--------------+------------------------------+------------------+-----------------------*/
Die Ergebnisse dieser Abfrage sind nur eine Schätzung der Auswirkungen der verlaufsbasierten Optimierung. Viele Faktoren können die Abfrageleistung beeinflussen, darunter die Verfügbarkeit von Slots, Änderungen der Daten im Zeitverlauf, Definitionen von Ansichten oder UDFs und Unterschiede bei den Abfrageparameterwerten.
Wenn das Ergebnis dieser Beispielabfrage leer ist, haben keine Jobs verlaufsbasierte Optimierungen verwendet oder alle Abfragen wurden vor mehr als 30 Tagen optimiert.
Diese Abfrage kann auf andere Messwerte zur Abfrageleistung wie total_slot_ms und total_bytes_billed angewendet werden. Weitere Informationen finden Sie im Schema für INFORMATION_SCHEMA.JOBS.