Google bigquery BigQuery要分区的完整表

Google bigquery BigQuery要分区的完整表,google-bigquery,Google Bigquery,我在一个表中有340 GB的数据(270天的数据)。现在计划将这些数据移动到分区表中 这意味着我将有270个分区。将此数据移动到分区表的最佳方式是什么 我不想运行270个查询,这是一个非常昂贵的操作。因此,寻找优化的解决方案 我有多张这样的桌子。我需要将所有这些表迁移到分区表 谢谢,如果您的数据在分片表中(即带有YYYYmmdd后缀),您可以使用“bq partition”命令。但是,如果数据位于一个表中,则必须在分区键列上应用不同的WHERE子句对其进行多次扫描。 我能想到的唯一优化是按层次进

我在一个表中有340 GB的数据(270天的数据)。现在计划将这些数据移动到分区表中

这意味着我将有270个分区。将此数据移动到分区表的最佳方式是什么

我不想运行270个查询,这是一个非常昂贵的操作。因此,寻找优化的解决方案

我有多张这样的桌子。我需要将所有这些表迁移到分区表


谢谢,

如果您的数据在分片表中(即带有
YYYYmmdd
后缀),您可以使用
“bq partition”
命令。但是,如果数据位于一个表中,则必须在分区键列上应用不同的WHERE子句对其进行多次扫描。 我能想到的唯一优化是按层次进行,即代替270个查询进行270次全表扫描——首先将表对半,然后将每个表对半等等。这样,您将需要为
2*log_2(270)=2*9=18
全表扫描付费

转换完成后,可以删除所有临时表以消除额外的存储成本。

我看到三个选项

  • 直接从原始表格中提取:
    操作(运行多少查询)=天[提取]=270
    完全扫描(在原始表格的完全扫描中测量的扫描数据量)=天=270
    成本,$=$5 x表格大小,TB xFull扫描=$5 x 0.34 x 270=$459.00

  • 分层的(递归)提取:(在Mosha的回答中描述)
    行动=2^log2(天)–2=510
    完整扫描=2*log2(天)=18
    成本,$=$5 x表格大小,TB xFull扫描=$5 x 0.34 x 18=$30.60

  • 集群提取(我将在几秒钟内进行描述)
    行动=天数+1=271
    完整扫描=[始终]2=2
    成本,$=$5 x表格大小,TB xFull扫描=$5 x 0.34 x 2=$3.40

  • 总结

    Method                              Actions Total Full Scans    Total Cost  
    Direct Extraction                       270              270       $459.00
    Hierarchical(recursive) Extraction      510               18        $30.60
    Clustered Extraction                    271                2         $3.40  
    
    毫无疑问,出于最实际的目的,Mosha的解决方案是可行的(我在大多数情况下使用它)
    它相对简单明了

    即使您需要运行查询510次,查询“相对”简单,编排逻辑也很容易用您通常使用的任何客户端实现
    而且节约成本是非常明显的! 从460美元降到31美元
    几乎15次下跌

    如果您-
    a) 想进一步降低成本,再降低9倍(因此总成本将降低135倍)
    b) 喜欢享受乐趣和更多的挑战 -看看第三种选择

    “聚类抽取”解释

    想法/目标
    步骤1
    我们希望将原始表转换为另一个包含270列的[单个]表–一列一天
    每列将保存原始表中相应日期的一个序列化行
    此新表中的总行数将等于大多数“繁重”日的行数
    这将只需要一个查询(见下面的示例)和一次完整扫描

    步骤2 在这个新表准备好之后——我们将逐日提取,只查询相应的列,并写入最终的每日表(每日表的模式与原始表的模式非常相同,所有这些表都可以预先创建) 这将需要运行270个查询,扫描大约相当于原始表的一个完整大小(这实际上取决于您的模式有多复杂,所以可能会有所不同) 在查询列时–我们需要反序列化行的值并将其解析回原始方案

    非常简化的示例:(此处使用BigQuery标准SQL)

    本例的目的只是为了给您指明方向,如果您会发现这个想法对您来说很有趣
    序列化/反序列化极为简化,以将重点放在idea上,而不是放在具体实现上,具体实现可能因情况而异(主要取决于模式)

    所以,假设原始表(theTable)看起来像下面这样

      SELECT  1 AS id, "101" AS x, 1 AS ts UNION ALL
      SELECT  2 AS id, "102" AS x, 1 AS ts UNION ALL
      SELECT  3 AS id, "103" AS x, 1 AS ts UNION ALL
      SELECT  4 AS id, "104" AS x, 1 AS ts UNION ALL
      SELECT  5 AS id, "105" AS x, 1 AS ts UNION ALL
      SELECT  6 AS id, "106" AS x, 2 AS ts UNION ALL
      SELECT  7 AS id, "107" AS x, 2 AS ts UNION ALL
      SELECT  8 AS id, "108" AS x, 2 AS ts UNION ALL
      SELECT  9 AS id, "109" AS x, 2 AS ts UNION ALL
      SELECT 10 AS id, "110" AS x, 3 AS ts UNION ALL
      SELECT 11 AS id, "111" AS x, 3 AS ts UNION ALL
      SELECT 12 AS id, "112" AS x, 3 AS ts UNION ALL
      SELECT 13 AS id, "113" AS x, 3 AS ts UNION ALL
      SELECT 14 AS id, "114" AS x, 3 AS ts UNION ALL
      SELECT 15 AS id, "115" AS x, 3 AS ts UNION ALL
      SELECT 16 AS id, "116" AS x, 3 AS ts UNION ALL
      SELECT 17 AS id, "117" AS x, 3 AS ts UNION ALL
      SELECT 18 AS id, "118" AS x, 3 AS ts UNION ALL
      SELECT 19 AS id, "119" AS x, 4 AS ts UNION ALL
      SELECT 20 AS id, "120" AS x, 4 AS ts
    
    第1步–转换表格并将结果写入TESTERABLE

    SELECT 
      num, 
      MAX(IF(ts=1, ser, NULL)) AS ts_1, 
      MAX(IF(ts=2, ser, NULL)) AS ts_2, 
      MAX(IF(ts=3, ser, NULL)) AS ts_3, 
      MAX(IF(ts=4, ser, NULL)) AS ts_4
    FROM (
      SELECT 
        ts, 
        CONCAT(CAST(id AS STRING), "|", x, "|", CAST(ts AS STRING)) AS ser, 
        ROW_NUMBER() OVER(PARTITION BY ts ORDER BY id) num
      FROM theTable
    )
    GROUP BY num
    
    诱惑将如下所示:

    num    ts_1        ts_2         ts_3        ts_4     
    1   1|101|1     6|106|2     10|110|3    19|119|4     
    2   2|102|1     7|107|2     11|111|3    20|120|4     
    3   3|103|1     8|108|2     12|112|3        null     
    4   4|104|1     9|109|2     13|113|3        null     
    5   5|105|1        null     14|114|3        null     
    6      null        null     15|115|3        null     
    7      null        null     16|116|3        null     
    8      null        null     17|117|3        null     
    9      null        null     18|118|3        null    
    
    在这里,我使用简单的串联进行序列化

    步骤2–提取特定日期的行并将输出写入相应的每日表
    请注意:在下面的示例中,我们为ts=2提取行:这对应于列ts_2

    SELECT
      r[OFFSET(0)] AS id,
      r[OFFSET(1)] AS x,
      r[OFFSET(2)] AS ts
    FROM (
      SELECT SPLIT(ts_2, "|") AS r 
      FROM tempTable 
      WHERE NOT ts_2 IS NULL
    )
    
    结果如下所示(这是预期的):


    我希望我有更多的时间写下来,所以如果遗漏了什么,不要判断太重——这是一个更有方向性的答案——但同时,这个例子是非常合理的,如果你有简单的模式——几乎不需要额外的思考。当然,对于记录,模式中的嵌套内容—最具挑战性的部分是序列化/反序列化—但这就是乐趣所在—以及额外的$saving

    我将在@Mikhail的答案中添加第四个选项

    DML查询

    • Action=1个要运行的查询
    • 完整扫描=1
    • 成本=$5 x 0.34=1.7$(比解决方案#1\o/便宜70倍)
    使用BiQuery的新DML功能,您可以将未分区的表转换为分区表,同时只对源表进行一次完整扫描

    为了说明我的解决方案,我将使用BQ的一个公共表,即
    bigquery公共数据:hacker\u news.comments
    。下面是表模式

    name    | type      | description
    _________________________________
    id      | INTGER    | ...
    _________________________________
    by      | STRING    | ...
    _________________________________
    author  | STRING    | ...
    _________________________________
    ...     |           |
    _________________________________
    time_ts | TIMESTAMP | human readable timestamp in UTC YYYY-MM-DD hh:mm:ss /!\ /!\ /!\
    _________________________________
    ...     |           |
    _________________________________
    
    我们要去参加聚会
    name    | type      | description
    _________________________________
    id      | INTGER    | ...
    _________________________________
    by      | STRING    | ...
    _________________________________
    author  | STRING    | ...
    _________________________________
    ...     |           |
    _________________________________
    time_ts | TIMESTAMP | human readable timestamp in UTC YYYY-MM-DD hh:mm:ss /!\ /!\ /!\
    _________________________________
    ...     |           |
    _________________________________
    
    #standardSQL
    CREATE TABLE my_dataset.comments_partitioned
    PARTITION BY DATE(time_ts)
    AS 
    SELECT *
    FROM `bigquery-public-data:hacker_news.comments`