如何在 BigQuery 中对大表进行排序?
Posted
技术标签:
【中文标题】如何在 BigQuery 中对大表进行排序?【英文标题】:How to sort a large table in BigQuery? 【发布时间】:2016-03-09 07:24:12 【问题描述】:我在 Google 的 BigQuery 中存储了大约 4GB 的数据,格式如下:
uuid | entity_name | property | value
---------------------------------------------------------------
abc | Person | first_name | John
def | Person | age | 45
abc | Person | age | 26
def | Person | first_name | Mary
...
我想得到按 uuid 排序的分页结果。但是,根据documentation,当“allowLargeResults”标志设置为 true 时,不能使用 ORDER BY 或 GROUP BY。 当然,查询如此大的表需要这样做。这种情况有解决方法吗?我尝试进行客户端排序,但是在成功获取前几页后,它会引发错误“现有连接被远程主机强制关闭”。
这是我的查询工作:
query = 'SELECT * FROM [Users.Events] ORDER BY uuid'
query_request =
'jobReference':
'projectId': project_id,
'job_id': str(uuid.uuid4())
,
'configuration':
'query':
'query': query,
'priority': 'BATCH' if BATCH_QUERY else 'INTERACTIVE',
'allowLargeResults' : True,
'destinationTable':
'projectId': project_id,
'datasetId': 'CrunchBase',
'tableId': 'AllProperties_query'
,
'createDisposition': 'CREATE_IF_NEEDED',
'writeDisposition': 'WRITE_TRUNCATE',
query_job = service.jobs().insert(
projectId=project_id,
body=query_request).execute(num_retries=2)
poll_job(service, query_job)
结果:
RuntimeError: u'reason': u'resourcesExceeded', u'message': u'Resources exceeded during query execution.', u'location': u'query'
编辑:尝试在分区内排序
如果我弄清楚如何按 entity_name 分区并按 uuid 排序,我可能会解决这个问题,但是以下查询不起作用:
SELECT
uuid, entity_name, property, value
OVER
(PARTITION BY entity_name ORDER BY uuid) AS entities
FROM [CrunchBase.AllProperties];
结果:
Query Failed
Error: Missing function in Analytic Expression at: 1.15 - 1.70
【问题讨论】:
我想,你误会GROUP BY
了!从 ORDER BY
开始 - 当您将“allowLargeResults
”设置为 true 时 - 您实际上要做的是 - 您允许 BigQuery 并行计算结果。正如您所想象的 - 如果您使用*** ORDER BY,这是不可能的。因此限制
我知道它会并行扫描行,我正在寻找这种情况的解决方法......是否有可能例如按 entity_name 对数据进行分区,并按 uuid 对每个分区进行排序?
答案取决于为什么需要对表格进行排序。如果是因为您需要将其导出到 BigQuery 之外 - 有一个解决方案。但如果排序后的数据将保留在 BigQuery 中 - 您能解释一下为什么需要排序吗?
@MoshaPasumansky:基本上它可以更轻松地在 BigQuery 之外导出数据。如果行是按 uuid 排序的,我可以扫描结果并随时随地创建新实体。如果它们未排序,则单个实体可能在第一行和最后一行具有属性,这意味着我必须在开始导出之前存储所有结果。
您应该查看 BigQuery 或 SQL 的一般文档,以了解您使用分区的方式不正确。 OVER (PARTITION ... )
表达式应该跟在函数字段之后,比如SUM(value)
等。
【参考方案1】:
要回答编辑中的问题,您需要实际指定一个分析函数以应用于该有序分区。由于您只需要每行的当前值,因此可以使用lead(x, 0)
。
对于您的查询,您可以这样写:
SELECT
uuid, entity_name,
LEAD(property, 0) OVER (PARTITION BY entity_name ORDER BY uuid) AS cur_property,
LEAD(value, 0) OVER (PARTITION BY entity_name ORDER BY uuid) AS cur_value,
FROM [CrunchBase.AllProperties]
【讨论】:
以上是关于如何在 BigQuery 中对大表进行排序?的主要内容,如果未能解决你的问题,请参考以下文章