按持续时间排名的 BigQuery 热门查询
长时间运行的查询会占用资源、延迟下游管道,并让等待结果的用户感到沮丧。此查询识别项目中运行时间最长的查询,包括执行时间、费用和一个运行时间与字节比率,有助于区分合理的大规模扫描和优化不良的查询。
为什么重要
执行时间不仅仅关乎费用。运行 30 分钟的查询会阻塞数据管道、延迟仪表板刷新或导致分析师分心。在 Editions 定价下,长时间运行的查询也会消耗更多槽位小时(最低 1 分钟计费)。减少查询持续时间可以同时改善费用和生产力。
工作原理
查询将执行时间计算为 end_time 和 start_time 之间的 TIMESTAMP_DIFF。还计算每 GiB 秒数比率:高值表示相对于处理的数据量查询较慢,暗示有优化潜力。
SQL 查询
Fill in your details to get a ready-to-run query:
-- Slowest queries ranked by wall-clock execution time
DECLARE lookback_days INT64 DEFAULT 7;
WITH jobs AS (
SELECT
user_email,
query,
project_id,
start_time,
end_time,
TIMESTAMP_DIFF(end_time, start_time, SECOND) AS duration_sec,
COALESCE(total_bytes_billed, 0) AS bytes_billed,
total_slot_ms,
ROW_NUMBER() OVER (PARTITION BY job_id ORDER BY end_time DESC) AS rn
FROM `your-project`.`region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL lookback_days DAY)
AND job_type = 'QUERY' AND state = 'DONE' AND total_slot_ms IS NOT NULL
),
deduplicated AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY query ORDER BY bytes_billed DESC) AS qrn
FROM jobs WHERE rn = 1
)
SELECT
user_email,
query,
project_id,
start_time,
duration_sec,
ROUND(SAFE_DIVIDE(total_slot_ms, duration_sec * 1000), 0) AS avg_slots,
...查询说明
两个级别的去重:首先按 job_id 删除重复的作业条目,然后按查询文本只显示每个唯一查询中最昂贵的执行。sec_per_gib 指标将执行时间除以计费字节数——高值意味着查询相对于读取的数据量较慢。
关键洞察
超过 10 分钟的查询可能正在扫描未分区的表或执行昂贵的 shuffle。
高 sec_per_gib 意味着查询受计算限制(复杂的 JOIN、排序、窗口函数),而不是 I/O 限制。
低 sec_per_gib 意味着查询快速扫描大量数据——可能受益于分区裁剪。
管道中长时间运行的查询可能导致所有下游依赖项出现级联延迟。
最佳实践
- 1
设置查询超时限制,防止失控查询无限期地消耗资源。
- 2
对于 ETL 管道,将长时间运行的整体查询拆分为更小的阶段性转换。
- 3
使用 EXPLAIN PLAN 识别最慢的阶段并专门优化它们。
- 4
考虑对探索性查询使用近似聚合函数(APPROX_QUANTILES、APPROX_TOP_COUNT)。