Jak snížit využití paměti?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
thunderbuff
Člen | 164
+
0
-

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
+
0
-

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
+
0
-

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