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