Отвечая на мой вопрос
Дополнительная память используется загрузкой отображения типов PHP и другой информацией о структуре данных, которая поставляется вместе с данными из BigQuery. К сожалению, я не смог найти способ уменьшить использование памяти ниже примерно 24 КБ на строку, умноженное на размер страницы. Если кто-то найдет способ уменьшить раздувание, сопровождающее данные, пожалуйста, напишите ниже .
Однако благодаря одному из комментариев я понял, что вы можете извлечь запрос непосредственно в CSV в Google Cloud Storage Bucket. Это действительно легко:
query = $bq->query($myQuery);
$queryResults = $bq->runQuery($query);
$qJobInfo = $queryResults->job()->info();
$dataset = $bq->dataset($qJobInfo['configuration']['query']['destinationTable']['datasetId']);
$table = $dataset->table($qJobInfo['configuration']['query']['destinationTable']['tableId']);
$extractJob = $table->extract('gs://mybucket/'.$filename.'.csv');
$table->runJob($extractJob);
Однако это все еще не решило мою проблему, так как мой набор результатов был больше 1 ГБ, поэтому мне пришлось использовать функцию разделения данных, добавив подстановочный знак.
$extractJob = $table->extract('gs://mybucket/'.$filename.'*.csv');
Это создало ~ 100 осколков в ведре. Они должны быть перекомпонованы с использованием gsutil compose <shard filenames> <final filename>
. Однако gsutil
позволяет создавать только 32 файла одновременно. Учитывая, что у меня будет переменное число шардов, как правило, выше 32, мне пришлось написать некоторый код для их очистки.
//Save above job as variable
$eJob = $table->runJob($extractJob);
$eJobInfo = $eJob->info();
//This bit of info from the job tells you how many shards were created
$eJobFiles = $eJobInfo['statistics']['extract']['destinationUriFileCounts'][0];
$composedFiles = 0; $composeLength = 0; $subfile = 0; $fileString = "";
while (($composedFiles < $eJobFiles) && ($eJobFiles>1)) {
while (($composeLength < 32) && ($composedFiles < $eJobFiles)) {
// gsutil creates shards with a 12 digit number after the filename, so build a string of 32 such filenames at a time
$fileString .= "gs://bucket/$filename" . str_pad($composedFiles,12,"0",STR_PAD_LEFT) . ".csv ";
$composedFiles++;
$composeLength++;
}
$composeLength = 0;
// Compose a batch of 32 into a subfile
system("gsutil compose $fileString gs://bucket/".$filename."-".$subfile.".csv");
$subfile++;
$fileString="";
}
if ($eJobFiles > 1) {
//Compose all the subfiles
system('gsutil compose gs://bucket/'.$filename.'-* gs://fm-sparkbeyond/YouTube_1_0/' . $filepath . '.gz') ==$
}
Примечание. Чтобы предоставить моему пользователю Apache доступ к gsutil
, мне пришлось разрешить пользователю создавать каталог .config
в корневом веб-каталоге. В идеале вы должны использовать PHP-библиотеку gsutil, но я не хотел, чтобы код раздувался.
Если у кого-то есть лучший ответ, пожалуйста, напишите его
Есть ли способ получить меньший вывод из библиотеки BigQuery, чем 24 КБ на строку?
Есть ли более эффективный способ очистки переменного количества осколков?