Jak snížit využití paměti?
- thunderbuff
- Člen | 164
Ahoj, ve svém projektu s Nette 2.0.8 pomocí Nette\Database exportuji data z databáze do CSV. Celý princip je jednoduchý, mám vlastní CSVResponse, která dostane objekt Selection, nad ním iteruje a vypisuje data na výstup, nějak takhle:
<?php
$handle = fopen("php://output", 'w');
foreach ($selection as $line) {
fputcsv($handle, $line, ";");
}
?>
Problém nastane ve chvíli, kdy potřebuji exportovat hodně záznamů (nad 100 000), export padá na 1GB memory limitu. Pokud jsem správně pochopil zdrojové kódy selection, tak si všechna data drží v paměti, toho se potřebuji zbavit, abych se vešel do limitu. Napadlo mě, že místo Selection bych mohl použít $connection->query(). Lze ze selection nějak dostat „finální“ SQL, které bych poslal do query? Skládání dotazu pomocí selection je velmi pohodlné, nerad bych se ho vzdal a $selection->sql vrací sql s otazníky místo proměnných.
Díky za každou radu!
Editoval thunderbuff (18. 10. 2013 15:34)
- thunderbuff
- Člen | 164
Odpovím si sám, stačilo ještě trochu prostudovat zdrojový kód selection:
<?php
$connection->queryArgs($selection->sql, $selection->getSqlBuilder()->getParameters());
?>
Uvidíme, zda to pomůže.
- s4muel
- Člen | 92
ak by to nepomohlo, tak zapisovanie do temp suboru namiesto pamate by mohlo
stacit.
je to sice o medzikrok viac, ale mne to pomohlo.
na http://php.net/….fputcsv.php je v komentaroch aj priklad na outputstream:
// Keep up to 12MB in memory, if becomes bigger write to temp file
$file = fopen('php://temp/maxmemory:'. (12*1024*1024), 'r+');
if($row = get_object_vars($xml->record[0])){ // First record
// First row contains column header values
foreach($row as $key => $value){
$header[] = $key;
}
fputcsv($file, $header,',','"');
foreach ($xml->record as $record) {
fputcsv($file, get_object_vars($record),',','"');
}
rewind($file);
$output = stream_get_contents($file);
fclose($file);
}
vyzera to pouzitelne