Google bigquery BigQuery—查询时间变得非常长

Google bigquery BigQuery—查询时间变得非常长,google-bigquery,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: Ap

最近我所有的查询都花费了太长的时间,但基本上它们都不消耗数据

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

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控制台得到的信息,它告诉我这个查询不使用任何数据(这是真的),只需要两秒钟

但当我在控制台中通过单击查询历史记录中的
runquery
再次运行此查询时,实际上需要27秒。然后,控制台中的
查询历史记录
显示此查询再次需要2秒钟

基本上这个数据集中的所有查询都有这个问题

我在这个数据集中有40000多个表

所以我的猜测是,在BQ实际运行查询之前,它首先定位要使用的表。然后开始执行查询,这是查询历史中的
开始时间

如果是这样的话,我应该如何解决它,为什么需要这么长时间

以下是我提到的问题(做了一些更改):

提前谢谢

PART 1
您可以使用API检查您关于开始时间之前延迟的理论,该API的作业ID取自BQ控制台中的查询历史记录。
正如您在-
statistics
中所看到的,除了
startTime
endTime
之外,参数还具有
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 
)
我知道,这可能看起来很傻,但是这个版本的解释统计(基于一些虚拟数据) 与所讨论的版本完全不同

我的猜测是,原始版本中的大量读取/计算阶段1/2可能是造成延迟的原因


猜猜看

正如在Mikhail问题的评论线程中所暗示的,大部分时间可能都花在评估查询中的
TABLE\u DATE\u RANGE
函数上。在查询统计中,此时间当前在
creationTime
startTime
之间

通常,当使用
表的日期范围
表的查询
、或
表的元表时,数据集中的数万或数十万个表会导致性能降低。我们正在努力更新我们的公共文件,以提及这一点


我的建议是,如果要在数据集中使用表通配符,请确保其中没有太多表。如果该解决方案对您来说不可行,请告知我们BigQuery是否可以支持一些东西,使您的用例在我们的应用程序中变得更容易。

Yikes!这是一个相当令人讨厌的问题。如果您正在做这么复杂的事情,我强烈建议您以编程方式发出查询,基本上是执行一系列查询,从中获取一个查询的输出,以编程方式生成下一个查询。在这里的问题中,我认为您提到的“count(user_id)”可能会导致在每个记录上迭代整个表以计算用户数。首先尝试单独发出count查询,然后在后续过程中引用其值。(云数据流可能是在此处使用BigQuery的另一种替代方法)。@MichaelAaronSafyan感谢您的回复。我不认为处理的行数是导致此问题的原因。正如我提到的,这个查询没有处理任何数据。表sessions\u some\u id\u 20151201为空。正如你所建议的,我试图从顶部删除
计数(user\u id)
,时间没有改变。非常感谢!你是对的。我尝试运行查询并检查
creationTime
startTime
endTime
。creationTime和
startTime
之间的延迟为25秒,而
startTime
endTime
之间的延迟接近0秒。你知道为什么第一次延误这么大吗?所以,你问题的第一部分相对简单。对于第二部分,请思考您还可以提供什么来帮助回答我的回答中添加的第2部分谢谢您的更新!太棒了!最好将
更改为
分区
where
的组合。但问题是我的
ds.sessions\u一些\u id\u 20151201
是空的。这就是我认为延迟是由表定位引起的原因。我刚刚运行了另一个实验,将
ds.sessions\u some\u id\u 20151201
ds.sessions\u some\u id\u 20151130
(两个空表)复制到另一个空数据集,当我在那里运行此查询时,不到一秒钟。
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 
)