如何在 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 中对大表进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

UNION表时如何在Bigquery中重新排列/重新排序嵌套的重复列

C:对大数据进行排序;不在记忆中

如何在 Google BigQuery 中进行表操作?

如何在 bigquery 中旋转我的 sql 表?

对大文件排序

如何选择第 n 列,并在 BigQuery 中对列的选择进行排序