PHP / Drupal ile büyük veri setlerini Taşıma

6 Cevap php

Ben bir veritabanı tablosundan ~ 700k kayıtları ile ilgilenen bir rapor sayfası var. Ben sonuçlarını kırmak için belleği kullanarak bir web sayfasında bu görüntüleyebilirsiniz. Ancak, PDF / CSV işlevlerine benim ihraç kerede tüm veri kümesini işleme ve çevresinde 250k satır benim 256MB bellek sınırına isabet değilim güveniyor.

Ben hafıza limitini artırmak rahat hissetmiyorum ve ben MySQL Sadece öncesi oluşturulan CSV hizmet etmek çıkışdosyası içine kaydetmek kullanma yeteneği yok. Ancak, gerçekten gibi bir şey kullanarak Drupal ile büyük veri setleri kadar hizmet veren bir yol göremiyorum:

$form = array();
$table_headers = array();
$table_rows = array();
$data = db_query("a query to get the whole dataset");
while ($row = db_fetch_object($data)) {
    $table_rows[] = $row->some attribute;
}

$form['report'] = array('#value' => theme('table', $table_headers, $table_rows);
return $form;

Aslında diziler dev bir diziye ne etrafında almanın bir yolu var mı? Şu anda ben bu nedeniyle Drupal ile anlamlı bir rapor sayfalarını sunabilir nasıl görmüyorum.

Teşekkürler

6 Cevap

Böyle büyük bir veri kümesi ile, gruplar halinde kırık olması zamanlı yoğun operasyonlar için izin Drupal Toplu API kullanmak istiyorsunuz. Bu operasyon ne kadar süreceğini bazı göstergesidir onlara bir ilerleme çubuğu verecektir çünkü aynı zamanda kullanıcılar için daha iyidir.

Ardından olana kadar her yeni parti üzerinde kendisine yeni kayıtlar eklemek, geçici bir dosya açarak toplu işlemi başlatın. Son sayfa cvs gibi verileri sunmak veya PDF dönüştürmek için son işlem yapabilirsiniz. Muhtemelen de bazı temizleme afterwords eklemek isterdim.

http://api.drupal.org/api/group/batch/6

Eğer PDF veya CSV üreten iseniz Drupal doğal işlevleri kullanmak gerekir. Ne döngü içindeyken çıkış dosyasına yazma konusunda? Bu şekilde, sadece bir sonuç kümesi belirli bir anda bellekte.

Şu an için dizide her şeyi saklamak $table_rows.

Eğer belleğin bir kısmını boşaltmak amacıyla veritabanı (örneğin, her öylesine ve çok hatları) onu okuyorsanız yaparken raporun en yerlerinde fışkırma değil miyim? Sadece bir kez bir csv yazmak için mümkün olmalıdır neden göremiyorum.

Ben hafıza limitini artırmak rahat hissetmiyorum

Hafıza limitini artırılması her php süreç bu bellek miktarını kullanmak anlamına gelmez. Ancak özel bir bellek sınırı ile php cli versiyonunu exec olabilir - ama bu da doğru bir çözüm değil ....

ve MySQL Sadece öncesi oluşturulan CSV hizmet etmek çıkışdosyası içine kaydetmek kullanma yeteneği yok

Sonra bir dizideki tüm tasarruf yok - veritabanı (IIRC tüm sonuç kümesi sınırlı php bellek dışında tamponlanana) onu getir zaman çıktı tamponunun her satırı yazmak. Veya dosya tamamlandı ve kapatıldığında sonra bir yönlendirme yapmak doğrudan bir dosyaya yazmak.

C.

Sen bir pager_query ile o içine belleği içerir ve 50-100 sayfa başına içine sonuçlarını ayrılmalıyız. O çok yardımcı olmalıdır. Eğer sayfalama kullanmak istiyorum ama kodu görmüyorum söylüyorlar.

Bu göz atın: http://api.drupal.org/api/function/pager_query/6

Akılda tutulması gereken bir diğer şey PHP5 (5.3 öncesi), yeni bir değişken için bir dizi atama veya bir işlev kopya dizi geçirmeden ve bir başvuru oluşturmak olmamasıdır. Aynı veri birçok kopyasını yaratıyor olabilir, ve hiçbiri unset veya kapsam dışında giderseniz onlar belleği boşaltmak için toplanan çöp olamaz. Mümkünse, orijinal dizide işlemleri gerçekleştirmek için başvurular kullanarak bellek tasarrufu yapabilirsiniz

function doSomething($arg){
  foreach($arg AS $var)
    // a new copy is created here internally: 3 copies of data exist
    $internal[] = doSomethingToValue($var);
  return $internal;
  // $arg goes out of scope and can be garbage collected: 2 copies exist
}
$var = array();
// a copy is passed to function: 2 copies of data exist
$var2 = doSomething($var);
// $var2 will be a reference to the same object in memory as $internal, 
//  so only 2 copies still exist

$ var fonksiyonunun dönüş değerine ayarlanırsa, eski değer çöp toplanabilir, ancak atama sonrasına kadar, yani daha fazla bellek yine kısa bir süre için gerekli olacak değil

function doSomething(&$arg){
  foreach($arg AS &$var)
    // operations are performed on original array data: 
    // only two copies of an array element exist at once, not the whole array
    $var = doSomethingToValue($var);  
  unset($var); // not needed here, but good practice in large functions
}
$var = array();
// a reference is passed to function: 1 copy of data exists
doSomething($var);