如何使用 Laravel 和 MySQL 获取大量记录?

How can fetching huge records using Laravel and MySQL?

我需要专家的建议和解决方案。我们在这里开发工作门户网站,处理大约 100 万条记录。我们正面临记录获取超时错误。如何使用 laravel 和 MySql 处理这些记录?

我们正在尝试按照以下步骤操作:

  1. 增加PHP执行时间
  2. MySql 索引
  3. 分页数

来自the docs

If you need to work with thousands of database records, consider using the chunk method. This method retrieves a small chunk of the results at a time and feeds each chunk into a Closure for processing. This method is very useful for writing Artisan commands that process thousands of records. For example, let's work with the entire users table in chunks of 100 records at a time:

DB::table('users')->orderBy('id')->chunk(100, function ($users) {
    foreach ($users as $user) {
        //
    }
});

在处理大型数据集时,您应该对结果进行分块。这使您可以处理较小的负载,减少内存消耗,并允许您 return 向用户发送数据,而其余的 fetched/processing。请参阅有关分块的 laravel 文档:

https://laravel.com/docs/5.5/eloquent#chunking-results

为了进一步加快速度,您可以利用多线程并生成并发进程,每个进程一次处理一个块。 Symfony 的 Symfony\Component\Process\Process class 使这很容易做到。

https://symfony.com/doc/current/components/process.html

嗨,我想这可能有帮助

    $users = User::groupBy('id')->orderBy('id', 'asc');

    $response = new StreamedResponse(function() use($users){
        $handle = fopen('php://output', 'w');
        // Add Excel headers
        fputcsv($handle, [
            'col1', 'Col 2'           ]);
        $users->chunk(1000, function($filtered_users) use($handle) {
            foreach ($filtered_users as $user) {
                // Add a new row with user data
                fputcsv($handle, [
                    $user->col1, $user->col2
                ]);
            }
        });
        // Close the output stream
        fclose($handle);
        }, 200, [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="Users'.Carbon::now()->toDateTimeString().'.csv"',
        ]);

        return $response;

Laravel 有一个用于此目的的惰性特性。我尝试了块和游标。游标进行一次查询并将大量数据放入内存中,如果数据库中有数百万条记录,这就没有用了。 Chunk 也不错,但在编写代码的方式上更懒惰。

use App\Models\Flight;
 
foreach (Flight::lazy() as $flight) {
    //
}

来源:https://laravel.com/docs/9.x/eloquent#chunking-results