【发布时间】: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)需要多长时间?无论哪种情况,加入都应该比您当前的循环更快。 -
我在上面做了一些编辑,我已经介绍了两种新方法
标签: python json google-bigquery