Menggunakan pengoptimalan berbasis histori
Panduan ini menjelaskan cara kerja pengoptimalan berbasis histori dan cara memperkirakan dampaknya untuk kueri.
Tentang pengoptimalan berbasis histori
Pengoptimalan berbasis histori secara otomatis menggunakan informasi dari eksekusi yang sudah selesai dari kueri yang sama atau serupa untuk menerapkan pengoptimalan tambahan dan lebih meningkatkan performa kueri, seperti waktu slot yang digunakan dan latensi kueri. Misalnya, eksekusi kueri pertama mungkin memerlukan waktu 60 detik, tetapi eksekusi kueri kedua mungkin hanya memerlukan waktu 30 detik jika pengoptimalan berbasis histori teridentifikasi. Proses ini berlanjut hingga tidak ada lagi pengoptimalan tambahan yang perlu ditambahkan.
Berikut adalah contoh cara kerja pengoptimalan berbasis histori dengan BigQuery:
| Jumlah eksekusi | Waktu slot kueri yang digunakan | Catatan |
|---|---|---|
| 1 | 60 | Eksekusi asli. |
| 2 | 30 | Pengoptimalan berbasis histori pertama diterapkan. |
| 3 | 20 | Pengoptimalan berbasis histori kedua diterapkan. |
| 4 | 21 | Tidak ada pengoptimalan tambahan berbasis histori yang akan diterapkan. |
| 5 | 19 | Tidak ada pengoptimalan tambahan berbasis histori yang akan diterapkan. |
| 6 | 20 | Tidak ada pengoptimalan tambahan berbasis histori yang akan diterapkan. |
Pengoptimalan berbasis histori hanya diterapkan jika ada keyakinan tinggi bahwa akan ada dampak positif pada performa kueri. Selain itu, jika pengoptimalan tidak meningkatkan performa kueri secara signifikan atau dapat menyebabkan performa yang lebih buruk, pengoptimalan tersebut akan dibatalkan dan tidak digunakan dalam eksekusi kueri tersebut di masa mendatang.
Meninjau pengoptimalan berbasis histori untuk tugas
Untuk meninjau pengoptimalan berbasis histori untuk tugas, Anda dapat menggunakan kueri SQL atau panggilan metode REST API.
SQL
Anda dapat menggunakan kueri untuk mendapatkan pengoptimalan berbasis histori untuk tugas.
Kueri harus menyertakan INFORMATION_SCHEMA.JOBS_BY_PROJECT
dan nama kolom query_info.optimization_details.
Dalam contoh berikut, detail pengoptimalan ditampilkan untuk tugas
yang disebut sample_job. Jika tidak ada pengoptimalan berbasis histori yang diterapkan, NULL akan
dihasilkan untuk 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;
Hasilnya akan mirip seperti berikut:
-- 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
Untuk mendapatkan detail pengoptimalan tugas, Anda dapat memanggil
metode jobs.get.
Dalam contoh berikut, metode jobs.get menampilkan detail pengoptimalan
(optimizationDetails)
dalam respons lengkap:
{
"jobReference": {
"projectId": "myProject",
"jobId": "sample_job"
}
}
Hasilnya akan mirip seperti berikut:
-- 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"
}
]
}
}
}
}
}
Memperkirakan dampak pengoptimalan berbasis histori
Untuk memperkirakan dampak pengoptimalan berbasis histori, Anda dapat menggunakan contoh kueri SQL berikut untuk mengidentifikasi kueri project dengan perkiraan peningkatan waktu eksekusi terbesar.
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;
Hasil kueri sebelumnya mirip dengan berikut ini jika pengoptimalan berbasis histori diterapkan:
/*--------------+------------------------------+------------------+-----------------------*
| 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 |
*--------------+------------------------------+------------------+-----------------------*/
Hasil kueri ini hanyalah perkiraan dampak pengoptimalan berbasis histori. Banyak faktor yang dapat memengaruhi performa kueri, termasuk, tetapi tidak terbatas pada ketersediaan slot, perubahan data dari waktu ke waktu, definisi tampilan atau UDF, dan perbedaan nilai parameter kueri.
Jika hasil kueri contoh ini kosong, berarti tidak ada tugas yang menggunakan pengoptimalan berbasis histori, atau semua kueri dioptimalkan lebih dari 30 hari yang lalu.
Kueri ini dapat diterapkan ke metrik performa kueri lainnya seperti
total_slot_ms dan total_bytes_billed. Untuk mengetahui informasi selengkapnya, lihat skema
untuk INFORMATION_SCHEMA.JOBS.