2015-01-22 14 views
7

Tôi đang thu thập khoảng 100 nghìn bản ghi từ các bảng tạm thời, thực hiện một số sửa đổi nhỏ về dữ liệu, tải xuống ảnh và sau đó đặt các trường tôi cần giữ trong bảng "chính". Điều này nhanh chóng khiến ứng dụng của tôi gặp sự cố khi hết bộ nhớ.Làm thế nào để sử dụng đoạn của Laravel để tránh hết bộ nhớ?

Tôi đọc các tài liệu rất ngắn gọn về cách sử dụng chunk() với ORO hùng hồn của Laravel nhưng không biết cách bắt đầu triển khai nó trong lớp học của tôi.

Đây là những gì tôi hiện đang thực hiện:

public function fire() 
{ 
    // Turn off query logging 
    DB::connection()->disableQueryLog(); 

    $feeds = RetsFeed::where('active','=',1)->get(); 
    foreach ($feeds as $feed) 
    { 

     $class = "TempListing{$feed->board}"; 

     $listings = $class::orderBy('MatrixModifiedDT','desc')->get(); 

     $listings->each(function($listing) use ($feed) { 
      ListingMigrator::migrateListing($listing,$feed); 
      echo "Feed: $feed->board\r\n"; 
      echo "SubcondoName: $listing->SubCondoName\r\n"; 
      echo "Development: $listing->Development\r\n"; 
      echo "\r\n"; 
     }); 
    } 

} 

Mỗi thức ăn chăn nuôi (hoặc nguồn dữ liệu) được đổ vào một bảng tạm thời trong một việc vặt khác nhau. Điều đó hoạt động tốt. Sau đó, tôi lấy tất cả các danh sách hte ra khỏi một bảng (trung bình khoảng 30k) và chạy phương thức ListingMigrator của tôi.

Tôi đặt đoạn này trong ví dụ này ở đâu? Nó sẽ thay thế dòng:

$listings = $class::orderBy('MatrixModifiedDT','desc')->get(); 

Tôi không hiểu rõ về việc đóng tài liệu hùng hồn. Đây là tất cả những gì có thể nói về nó và đây là đoạn mã nguồn từ trang Laravel:

User::chunk(200, function($users) 
{ 
    foreach ($users as $user) 
    { 
     // 
    } 
}); 

Trả lời

14

Cuộc gọi chunk nên thay thế các get cuộc gọi - nó được thiết kế để làm việc trên() đối tượng xây dựng truy vấn-get trước .

$listings = $class::orderBy('MatrixModifiedDT','desc'); 

$listings->chunk(200, function($listings) use($feed) { 
    $listings->each(function($listing) use ($feed) { 
     ListingMigrator::migrateListing($listing,$feed); 
     echo "Feed: $feed->board\r\n"; 
     echo "SubcondoName: $listing->SubCondoName\r\n"; 
     echo "Development: $listing->Development\r\n"; 
     echo "\r\n"; 
    }); 
}); 
+1

Điều này dường như hoạt động như một sự quyến rũ! Cảm ơn SO nhiều vì sự hào phóng của bạn khi trả lời. Một câu hỏi của tôi là cách chúng tôi xác định số 200 cho đoạn. Sự hiểu biết của tôi là nó xử lý nhiều và sau đó về cơ bản "bắt đầu lại" vì thiếu một từ tốt hơn. Nó sẽ không được an toàn ot giữ số này thực sự thấp, như thậm chí 10? Là chi phí duy nhất để thực hiện các cuộc gọi cơ sở dữ liệu bổ sung? –

+2

@ChrisFarrugia Kích thước chunk là khá tùy ý và yêu cầu khó duy nhất là nó đủ nhỏ để bạn không hết RAM trong một đoạn. Nếu cơ sở dữ liệu của bạn không quan tâm đến tải, khối 10 là tốt. Chunks 200 cũng có khả năng tốt. – ceejayoz

+2

Lưu ý: nếu 'chunk' liên quan đến việc sửa đổi các bản ghi có thể ảnh hưởng đến truy vấn, chẳng hạn như xóa mềm, xóa cứng, thay đổi cột trong truy vấn v.v ..., thì bạn cần bao quanh đoạn văn với câu lệnh while. Vui lòng xem http://stackoverflow.com/questions/32700537/eloquent-chunk-missing-half-the-results và có thể http://laravel.io/forum/09-22-2015-chunk-missing-half-the -results? page = 1 – brianlmerritt

Các vấn đề liên quan