javascript - Google BigQuery Python 库下载结果的速度是 Node JS 库的 2 倍
问题描述
我一直在进行测试,以比较 Google BigQuery Python 客户端库与 Node JS 库下载查询结果的速度。看起来,开箱即用的 Python 库下载数据的速度大约是 Javascript Node JS 客户端的两倍。为什么呢?
下面我提供了两个测试,一个在 Python 中,一个在 Javascript 中。我选择了usa_names
BigQuery 的公共数据集作为示例。该usa_1910_current
数据集中的表大约有 600 万行,180Mb
大小约为。我有一个 200Mb 光纤下载链接(有关最后一英里的信息)。数据打包到 pandas 数据帧后,大约为 1.1Gb(包括 Pandas 开销)。
蟒蛇测试
from google.cloud import bigquery
import time
import pandas as pd
bq_client = bigquery.Client("mydata-1470162410749")
sql = """SELECT * FROM `bigquery-public-data.usa_names.usa_1910_current`"""
job_config = bigquery.QueryJobConfig()
start = time.time()
#---------------------------------------------------
query_job = bq_client.query(
sql,
location='US',
job_config=job_config)
#---------------------------------------------------
end = time.time()
query_time = end-start
start = time.time()
#---------------------------------------------------
rows = list(query_job.result(timeout=30))
df = pd.DataFrame(data=[list(x.values()) for x in rows], columns=list(rows[0].keys()))
#---------------------------------------------------
end = time.time()
iteration_time = end-start
dataframe_size_mb = df.memory_usage(deep=True).sum() / 1024 ** 2
print("Size of the data in Mb: " + str(dataframe_size_mb) + " Mb")
print("Shape of the dataframe: " + str(df.shape))
print("Request time:", query_time)
print("Fetch time:", iteration_time)
节点 JS 测试
// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');
const moment = require('moment')
async function query() {
const bigqueryClient = new BigQuery();
const query = "SELECT * FROM `bigquery-public-data.usa_names.usa_1910_current`";
const options = {
query: query,
location: 'US',
};
// Run the query as a job
const [job] = await bigqueryClient.createQueryJob(options);
console.log(`Job ${job.id} started.`);
// Wait for the query to finish
let startTime = moment.utc()
console.log('Start: ', startTime.format("YYYY-MM-DD HH:mm:ss"));
const [rows] = await job.getQueryResults();
let endTime = moment.utc()
console.log('End: ', endTime.format("YYYY-MM-DD HH:mm:ss"));
console.log('Difference (s): ', endTime.diff(startTime) / 1000)
}
query();
180Mb 数据的 Python 库测试结果:
- 以 Mb 为单位的数据大小:1172.0694370269775 Mb
- 数据框的形状:(6028151, 5)
- 请求时间:3.58441424369812
- 获取时间:388.0966112613678 <-- 这是6.46 分钟
180Mb 数据的 Node JS 库测试结果:
- 开始时间:2019-06-03 19:11:03
- 结束:2019-06-03 19:24:12 <- 约13分钟
为了进一步参考,我还对 2Gb 表进行了测试......
具有 2Gb 数据的 Python 库测试结果:
- 数据大小(Mb):3397.0339670181274 Mb
- 数据框的形状:(1278004, 21)
- 请求时间:2.4991791248321533
- 获取时间:867.7270500659943 <-- 这是14.45 分钟
2Gb 数据的 Node JS 库测试结果:
- 开始时间:2019-06-03 15:30:59
- 结束: 2019-06-03 16:02:49 <-- 相差不到31分钟
解决方案
正如我所看到的,Node JS 使用分页来管理数据集,而 Python 看起来像是带来了整个数据集并开始使用它。
这可能会影响 Node JS 客户端库的性能,我的建议是查看两个客户端的源代码并经常阅读 Google Cloud 博客,其中 Google 有时会发布使用其产品的提示和最佳实践,作为本文示例:测试 Cloud Pub/Sub 客户端以最大限度地提高流式传输性能。
推荐阅读
- android - 在 Firebase testLab 中运行 Screenshotter 时出错
- excel - 上一个文档上的 BeforeSave(Save As) 事件的事件
- python - 我正在尝试为我的学校网站制作网络爬虫
- javascript - 从谷歌电子表格到电报机器人的日期格式
- typescript - 转换 Observable 的最佳方法
到可观察的 - ruby-on-rails - 有什么方法可以检查用户是否自 x 个月以来不活跃
- html - 模式属性验证在 html 输入中输入的文本的频率
- python - 我将视频捕获到帧中。我怎样才能把它找回来和原来的一样
- mediapipe - MediaPipe 的 Palm Tracking 是否有 javascript 实现?
- javascript - 递归得到“超出最大调用堆栈大小”Javascript