6月,BQ团队宣布支持日期分区表.但是指南缺少如何将旧的非分区表迁移到新样式中.
我正在寻找一种方法来更新几个或如果不是所有表到新的样式.
在DAY类型之外还划分了其他可用选项吗?BQ UI是否显示此内容,因为我无法从BQ Web UI创建这样的新分区表.
小智 15
对我有用的是以下一组直接应用于大查询的查询(大查询创建新查询)。
CREATE TABLE (new?)dataset.new_table 
PARTITION BY DATE(date_column) 
AS SELECT * FROM dataset.table_to_copy;
然后作为下一步,我放下桌子:
DROP TABLE dataset.table_to_copy;
我 只使用第 2 步从https://fivetran.com/docs/warehouses/bigquery/partition-table得到了这个解决方案
Mik*_*ant 14
来自Pavan的回答:请注意,这种方法会向您收取查询源表的扫描成本.
来自Pentium10评论:假设我有几年的数据,我需要为每天准备不同的查询并运行所有这些,并假设我有1000天的历史,我需要从源头支付1000倍的完整查询价格表?
我们可以看到 - 这里的主要问题是每天都要进行全面扫描.剩下的不是问题,可以在任何选择的客户端轻松编写脚本
所以,下面是 - 如何分区表,同时避免每天全表扫描?
下面逐步说明该方法
它足够通用,可以扩展/适用于任何真正的用例 - 同时我正在使用bigquery-public-data.noaa_gsod.gsod2017,我将"运动"限制在10天内以保持其可读性   
步骤1 - 创建数据透视表
在此步骤中,我们
a)将每行的内容压缩为记录/数组
,
b)将它们全部放入相应的"每日"列  
#standardSQL
SELECT
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170101' THEN r END) AS day20170101,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170102' THEN r END) AS day20170102,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170103' THEN r END) AS day20170103,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170104' THEN r END) AS day20170104,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170105' THEN r END) AS day20170105,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170106' THEN r END) AS day20170106,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170107' THEN r END) AS day20170107,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170108' THEN r END) AS day20170108,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170109' THEN r END) AS day20170109,
  ARRAY_CONCAT_AGG(CASE WHEN d = 'day20170110' THEN r END) AS day20170110
FROM (
  SELECT d, r, ROW_NUMBER() OVER(PARTITION BY d) AS line
  FROM (
    SELECT 
      stn, CONCAT('day', year, mo, da) AS d, ARRAY_AGG(t) AS r
    FROM `bigquery-public-data.noaa_gsod.gsod2017` AS t 
    GROUP BY stn, d
  ) 
)
GROUP BY line  
使用pivot_table(或任何名称首选)在Web UI中运行上述查询作为目标
我们可以看到 - 这里我们将得到10列的表 - 一天一列,每列的模式是原始表的模式的副本:
步骤2 - 逐个处理分区仅扫描相应列(无全表扫描) - 插入相应的分区
#standardSQL
SELECT r.*
FROM pivot_table, UNNEST(day20170101) AS r
从Web UI运行上面的查询,目标表名为mytable $ 20160101
你可以在第二天运行
#standardSQL
SELECT r.*
FROM pivot_table, UNNEST(day20170102) AS r
现在你应该有目标表作为mytable $ 20160102等等
您应该能够使用您选择的任何客户端自动执行/编写此步骤
如何使用上述方法有很多变化 - 这取决于你的创造力
注意:BigQuery允许表中最多10000列,因此一年中相应日期的365列绝对不是问题:o)除非对新分区的回程有多大限制 - 我听说(但没有现在还有机会检查,现在回来的时间不超过90天
更新
请注意:上面的版本有一些额外的逻辑,将所有聚合单元格打包成尽可能少的最终行数.
ROW_NUMBER() OVER(PARTITION BY d) AS line
然后
GROUP BY line
一起
ARRAY_CONCAT_AGG(…)
做这件事      
当原始表中的行大小不是那么大时,这种方法很有效,因此最终组合行大小仍然在BigQuery的行大小限制内(我相信现在是10 MB)
如果源表的行大小已接近该限制 - 请使用以下调整后的版本
在此版本中 - 删除分组,使每行只有一列的值
#standardSQL
SELECT
    CASE WHEN d = 'day20170101' THEN r END AS day20170101,
    CASE WHEN d = 'day20170102' THEN r END AS day20170102,
    CASE WHEN d = 'day20170103' THEN r END AS day20170103,
    CASE WHEN d = 'day20170104' THEN r END AS day20170104,
    CASE WHEN d = 'day20170105' THEN r END AS day20170105,
    CASE WHEN d = 'day20170106' THEN r END AS day20170106,
    CASE WHEN d = 'day20170107' THEN r END AS day20170107,
    CASE WHEN d = 'day20170108' THEN r END AS day20170108,
    CASE WHEN d = 'day20170109' THEN r END AS day20170109,
    CASE WHEN d = 'day20170110' THEN r END AS day20170110
FROM (
    SELECT 
        stn, CONCAT('day', year, mo, da) AS d, ARRAY_AGG(t) AS r
    FROM `bigquery-public-data.noaa_gsod.gsod2017` AS t 
    GROUP BY stn, d
)
WHERE d BETWEEN 'day20170101' AND 'day20170110'
正如您现在所看到的 - 数据透视表(sparce_pivot_table)足够稀疏(相同的21.5 MB,但现在是114,089行,而pivot_table中的11,584行),因此它的平均行大小为190B,初始版本为1.9KB.根据示例中的列数,这显然要少10倍.
所以在使用这种方法之前,需要做一些数学计算/估计什么以及如何做!  
仍然:数据透视表中的每个单元格都是原始表中整行的JSON表示.它不仅包含原始表中的行的值,而且还包含一个模式
因此它非常冗长 - 因此单元格的大小可能比原始大小大许多倍[这限制了这种方法的使用......除非你变得更有创意:o)......这里仍有很多领域申请:o)]
在BigQuery中推出新功能之前,还有另一种(便宜得多的)方法可以使用Cloud Dataflow对表进行分区.我们使用这种方法而不是运行数百个SELECT *语句,这将花费我们数千美元.
partition命令在BigQuery中创建分区表BigQuery.IO.Read器读取表BigQuery.IO.Write为每天/分片创建一个接收器,使用分区装饰器语法写入相应的分区 -"$YYYYMMDD"您仍然需要为Dataflow管道付费,但这只是SELECT *在BigQuery 中使用多个成本的一小部分.
截至今天,您现在可以通过查询并指定分区列,从非分区表创建分区表.您将在原始(未分区)表上支付一次全表扫描.注意:目前处于测试阶段.
要从查询结果创建分区表,请将结果写入新目标表.您可以通过查询分区表或非分区表来创建分区表.您无法使用查询结果将现有标准表更改为分区表.
如果您今天有日期分片表,您可以使用这种方法:
如果您有一个要转换为分区表的非分区表,您可以尝试运行 SELECT * 查询并允许大结果并使用表的分区作为目标的方法(类似于您重新声明数据的方式)划分):
https://cloud.google.com/bigquery/docs/creating-partitioned-tables#restating_data_in_a_partition
请注意,此方法将向您收取查询的源表扫描成本,次数与查询次数相同。
在接下来的几个月里,我们正在努力使这种情况变得更好。
| 归档时间: | 
 | 
| 查看次数: | 7523 次 | 
| 最近记录: |