Google大查询+ PHP ->如何在不耗尽内存的情况下获取大型数据集


Google Big Query + PHP -> How to fetch a large data set without running out of memory

我试图在BigQuery/PHP(使用google PHP SDK)中运行查询,返回一个大型数据集(可以是100,000 - 10,000,000行)。

$bigqueryService = new Google_BigqueryService($client);
$query = new Google_QueryRequest();
$query->setQuery(...);
$jobs = $bigqueryService->jobs;
$response = $jobs->query($project_id, $query); 
//query is a syncronous function that returns a full dataset

下一步是允许用户以CSV文件的形式下载结果。

当数据集太大(内存限制)时,上面的代码将失败。我有哪些选项可以在较低的内存使用情况下执行此操作?

(我认为一个选项是将结果保存到另一个表与BigQuery,然后开始做部分取与LIMIT和OFFSET,但我认为一个更好的解决方案可能是可用的..)

Thanks for the help

可以直接从Bigquery导出数据

https://developers.google.com/bigquery/exporting-data-from-bigquery

你可以用PHP运行一个API调用来做导出(你不需要BQ工具)

您需要设置作业configuration.extract.destinationFormat参见参考

再详细说明一下Pentium10的答案

最多可以导出1GB的json格式文件。然后你可以逐行读取文件,这将最大限度地减少你的应用程序使用的内存,然后你可以使用json_decode的信息。

导出的建议很好,我只是想提一下还有另一种方法。

你正在调用的查询API (jobs.query())没有返回完整的数据集;它只返回一页数据,即结果的前2mb。您可以设置maxResults标志(在这里描述)来将此限制为一定数量的行。

如果返回的行数少于表中的行数,则将在响应中获得pageToken字段。然后,您可以通过提供作业ID(也在查询响应中)和页面令牌,使用jobs.getQueryResults() API获取剩余部分。这将继续返回新行和一个新的页令牌,直到到达表的末尾。

下面的示例显示了运行查询并逐页获取结果的代码(java和python)。

在API中也有一个选项,通过在URL查询字符串中指定alt='csv'直接转换为CSV,但我不确定如何在PHP中做到这一点。

我不确定你是否还在使用PHP,但答案是:

$options = [
    'maxResults' => 1000,
    'startIndex' => 0
];
$jobConfig = $bigQuery->query($query);
$queryResults = $bigQuery->runQuery($jobConfig, $options);
foreach ($queryResults as $row) {
    // Handle rows
}