更快地解析 BigQuery JSON 结果
Posted
技术标签:
【中文标题】更快地解析 BigQuery JSON 结果【英文标题】:Faster parsing of BigQuery JSON results 【发布时间】:2019-10-24 13:03:26 【问题描述】:我正在构建一个使用 BigQuery 作为数据源的 API。我们在数据存储、分区和查询优化方面做了大量工作,但是,我在有效解析查询结果方面遇到了一些麻烦。例如,在某些情况下,有 50 多行 JSON,我看到解析需要 3 秒或更长时间,这在查询执行和 HTTP 请求/响应之上远非理想。
下面是我使用公共 BigQuery 数据集所做的简化版本,我的查询要复杂得多,但是解析是相同的,这是我需要一些帮助的地方。
from google.cloud import bigquery
import json
sql = """
SELECT TO_JSON_STRING(t) FROM (
SELECT * FROM
`bigquery-public-data.hacker_news.stories`
LIMIT 50 OFFSET 0
) as t
"""
client = bigquery.Client()
job_config = bigquery.QueryJobConfig()
query_job = client.query(sql,job_config=job_config)
results = query_job.result()
# Begin parsing results to valid
# JSON for API response
json_response = '['
i = 0
for row in results:
json_response = json_response + row[0]
if i != total_rows:
json_response = json_response + ","
i += 1
json_response = json_response + ']'
print(json_response)
我尝试遵循here 中列出的一些性能提示,但不断遇到我无法克服的错误。
注意:我是 Python 的新手,在过去的几年里一直使用 Ruby 编写代码。
编辑: 我尝试了几种构建 JSON 响应的替代方法,针对 Micah 的评论,我运行了一些分析,结果如下。
版本1(原版如上)
json_response = '['
i = 0
for row in results:
json_response = json_response + row[0]
if i != total_rows:
json_response = json_response + ","
i += 1
json_response = json_response + ']'
建立响应的平均时间 = 1.7962 秒
第 2 版
json_list = [ json.loads(row[0]) for row in results]
json_response = json.dumps(json_list)
构建响应的平均时间 = 2.4789 秒
我猜这里 json.loads 和 json.dumps 会增加延迟。
版本 3(基于 Micah 的建议)
a = [row[0] for row in results]
json_response = ",".join(a)
建立响应的平均时间 = 1.9623 秒
我更喜欢 V2&3 的代码,但 V1 仍然是最快的方法,尽管速度很慢。
【问题讨论】:
大的 JSON 数据从何而来?它是来自存储 JSON 的某个列还是作为您的示例查询,您形成了一个要从 BigQuery 返回的 JSON。解决方案可能不同。 它来自后来/第二个选项。该表有很多列,使用 TO_JSON_STRING() 命令返回 JSON 行。 这可能有助于进行更多分析。a =[row[0] for row in results]
需要多长时间? ",".join(a)
需要多长时间?无论哪种情况,加入都应该比您当前的循环更快。
我在上面做了一些编辑,我已经介绍了两种新方法
【参考方案1】:
我通常是这样做的:
from google.cloud import bigquery
import json
# BigQuery Setup and Query
project_name = 'my_project'
client = bigquery.Client(project=project_name)
query = 'select to_json_string(t) as my_stuff from schema.dataset'
job_config = bigquery.QueryJobConfig()
job_config.use_query_cache = False
query_job = client.query(query, job_config = job_config)
results = query_job.result()
json_list = []
for row in results:
json_list.append(row.my_stuff)
with open('data.json', 'w') as f:
json.dump(json_list,f)
如果您需要字段名称或多个字段,请使用to_json_string(struct(t))
或to_json_string(struct(a,b,c) as values))
【讨论】:
以上是关于更快地解析 BigQuery JSON 结果的主要内容,如果未能解决你的问题,请参考以下文章
Google BigQuery:将 ExecuteQuery 结果以 json 格式上传到 Google Cloud Storage
SwiftyJson 是不是可以更快地解析 swift json?
使用 Java 从 BigQuery 到 BigQuery 表的表复制中的 JSON 解析错误
如何使用 JSON_EXTRACT 或 JSON_EXTRACT_SCALAR 在 Big Query 中读取多级 JSON 数据