BigQuery - 查询时间变得非常长

时间:2016-01-14 04:37:41

标签: google-bigquery

最近我的所有查询都需要很长时间,但基本上所有查询都不会消耗任何数据。

例如,对于一个非常简单的查询

Start Time: Jan 14, 2016, 12:35:13 PM
End Time: Jan 14, 2016, 12:35:15 PM
Bytes Processed: 0 B
Bytes Billed: 0 B
Billing Tier: 1
Destination Table: ****************.******************
Write Preference: Append to table
Allow Large Results: true
Flatten Results: true

这是我从BQ控制台获得的信息,它告诉我这个查询不消耗任何数据(这是真的),只需要两秒钟。

但是,当我通过点击查询历史记录中的Run Query在控制台中再次运行此查询时,实际上需要27秒。然后,控制台中的Query History显示此查询再次花费2秒。

基本上,此数据集中的所有查询都存在此问题。

此数据集中有超过40000个表。

所以我的猜测是,在BQ实际运行查询之前,它首先找到将要使用的表。然后它开始执行查询,这里是查询历史记录中的start time

如果是这种情况,我该如何解决?为什么需要这么长时间?

这是我提到的查询(已经做了一些更改):

select "some_id", '2015-12-01', if (count(user_id) == 0, NULL, sum(users_in_today_again) / count(user_id)) as retention
from
(
select
  users_in_last_day.user_id as user_id,
  if(users_in_today.user_id is null, 0, 1) as users_in_today_again
FROM
(
select user_id
from
  table_date_range(ds.sessions_some_id_, date_add(timestamp('2015-12-01'), -1, "DAY"), date_add(timestamp('2015-12-01'), -1, "DAY"))
group by user_id
) as users_in_last_day
left join
(
select user_id
from table_date_range(ds.sessions_some_id_, timestamp('2015-12-01'), timestamp('2015-12-01'))
group by user_id
) as users_in_today
on users_in_last_day.user_id = users_in_today.user_id
)

提前致谢!

2 个答案:

答案 0 :(得分:3)

PART 1

您可以使用Jobs:Get API和BQ控制台中查询历史记录中的jobid来检查有关延迟开始时间的理论。
正如您在Job Resources - statistics参数中看到的那样,startTimeendTime也有creationTime

PART 2

在黑暗中拍摄,但请尝试以下

SELECT "some_id", '2015-12-01', IF (COUNT(user_id) == 0, NULL, SUM(users_in_today_again) / COUNT(user_id)) AS retention
FROM
(
  SELECT
    users_in_last_day.user_id AS user_id,
    IF(users_in_today.user_id IS NULL, 0, 1) AS users_in_today_again
  FROM
  (
    SELECT user_id FROM (
      SELECT user_id, ROW_NUMBER() OVER(PARTITION BY user_id) AS pos
      FROM TABLE_DATE_RANGE(ds.sessions_some_id_, DATE_ADD(TIMESTAMP('2015-12-01'), -1, "DAY"), DATE_ADD(TIMESTAMP('2015-12-01'), -1, "DAY"))
    ) WHERE pos = 1
  ) AS users_in_last_day
  LEFT JOIN
  (
    SELECT user_id FROM (
      SELECT user_id, ROW_NUMBER() OVER(PARTITION BY user_id) AS pos
      FROM TABLE_DATE_RANGE(ds.sessions_some_id_, TIMESTAMP('2015-12-01'), TIMESTAMP('2015-12-01'))
    ) WHERE pos = 1
  ) AS users_in_today
  ON users_in_last_day.user_id = users_in_today.user_id 
)

我知道,这个版本可能看起来很傻,但解释统计数据(基于一些虚拟数据) enter image description here 与版本完全不同 enter image description here

我的猜测是原始版本的重读/计算Stage1 / 2可能导致问题延迟

猜猜

答案 1 :(得分:0)

正如米哈伊尔问题的评论主题中暗示的那样,大部分时间可能花在评估查询中的TABLE_DATE_RANGE函数上。此时间目前在查询统计信息中占creationTimestartTime之间。

通常,数据集中的数十或数十万个表在使用TABLE_DATE_RANGETABLE_QUERY<dataset>.__TABLES__元表时会导致性能下降。我们正在努力更新我们的公共文档以提及此内容。

我的建议是,如果要在数据集上使用表通配符,请确保其中没有太多表。如果该解决方案对您来说不可行,请告诉我们BigQuery是否可以支持在issue tracker上使您的用例更容易的内容。