我正在学习 SQL,在学习指导示例时,我喜欢尝试编写自己的查询来回答问题,然后再查看课程建议如何执行。在本例中,我使用了一种稍微不同的方法,并且我有兴趣将我的方法与给定的示例进行比较。
指导示例使用 BigQuery 上提供的名为 bigquery-public-data.new_york_citibike 的公共数据集。提出的问题是找到行程持续时间最超过其起始自行车站的平均行程持续时间的 Citibike 骑行。
这是指导示例中建议的代码:
SELECT
starttime,
start_station_id,
tripduration,
(
SELECT ROUND(AVG(tripduration),2)
FROM bigquery-public-data.new_york_citibike.citibike_trips
WHERE start_station_id = outer_trips.start_station_id
) AS avg_duration_for_station,
ROUND(tripduration - (
SELECT AVG(tripduration)
FROM bigquery-public-data.new_york_citibike.citibike_trips
WHERE start_station_id = outer_trips.start_station_id), 2) AS difference_from_avg
FROM bigquery-public-data.new_york_citibike.citibike_trips AS outer_trips
ORDER BY difference_from_avg DESC
LIMIT 25
这是我在查看他们的解决方案之前想出的代码:
SELECT
starttime,
start_station_id,
tripduration,
station_averages.station_average AS station_avg,
ROUND (tripduration - station_averages.station_average,2) AS diff_from_station_avg
FROM `bigquery-public-data.new_york_citibike.citibike_trips`
JOIN (
SELECT
start_station_id AS station_id,
ROUND(AVG(tripduration),2) as station_average
FROM `bigquery-public-data.new_york_citibike.citibike_trips`
GROUP BY station_id
) AS station_averages
ON start_station_id = station_averages.station_id
ORDER BY 5 DESC
LIMIT 25
看看我的代码与他们的代码,我认为我的代码会运行得更快,因为在制作 JOIN 表时,我只计算每个站点的平均行程持续时间一次。另一方面,他们的代码计算每个站点平均值的次数与该站点在表中出现的次数相同。
为了比较这两种方法,我将它们分别放在 BigQuery 选项卡中,运行它们并验证它们执行相同的操作后,我查看了每个查询的“作业信息”。第一个由我正在学习的课程提供,花了“0 秒”,而我的则花了“1 秒”。
为了更好地看到比较,我尝试将每个查询的最后一行编辑为
LIMIT 250
...然后是 2500、25000 等。他们的查询运行速度只比我的快大约 1 秒,直到我将限制一路增加到 250 万。然后,我的跑了17秒,他们的跑了18秒。
任何人都可以帮助我理解这里发生了什么吗?当我猜测我的查询效率更高时,我对代码的理解是否正确?为什么他们和我的处理时间不同?为什么更改限制甚至会影响时间,因为它必须计算表中每一行的所有结果才能按第 5 列进行排序?
我希望这些问题有意义。预先感谢您的任何指示。
评估 BigQuery 中的查询性能,这取决于一些因素:
例如:仅查询需要的列。在查询中将 LIMIT 子句应用于 SELECT * 查询不会影响读取的数据量。使用 SELECT * EXCEPT 从结果中排除一列或多列。它可以更快地执行您的查询。
其中许多因素都可以通过查询计划观察到。为提交到 BigQuery 的每个查询生成一个
query plan
。我们可以看到执行统计信息,例如读取的字节数和消耗的时隙时间。
您可以通过此链接优化查询计算,让您的查询更加高效。