优化数据库查询 - 扩展大数据 - Laravel 5

时间:2015-07-01 17:10:30

标签: php mysql sql laravel-5 chunks

我一直在研究使用Laravel 5的网络应用程序。它在Windows 8.1 PC上的localhost(xampp)上运行。 4GB RAM,2,67GHz处理器,非常简单。

我在大多数时间查询的表包含很多行(10.000给出或接受) - 这么多写一条路径:

return User::all(); 

运行它只会返回一个白色屏幕。有时,Chrome控制台会列出500(内部服务器错误)。

显示查询之前的回声或打印但在执行之后没有任何内容。查询另一个模型(其表只有2行)可以正确返回数据。

这使我得出结论,我的服务器在这个数据量方面的扩展性不佳。我试图解决这个问题。

User::all()->chunk(200, function($chunkOfTickets){ /*some code*/});

我希望将数据拆分成块,以便在服务器上更容易。但是,这不起作用,因为Eloquent首先获取所有数据(因为它无法处理它而破坏),然后才将其分成块。

感谢阅读。

编辑:只是反复测试,要求越来越多的数据量。约为26000行(27000并返回内存不足错误)。

正如评论中所述,php日志说明了这一点。显然,在Laravel显示错误消息

之前,我要求这么多内存崩溃了
[01-Jul-2015 17:27:51 UTC] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 8376445 bytes) in C:\xampp\htdocs\gamescaffold\vendor\laravel\framework\src\Illuminate\Support\Collection.php on line 791

额外修改

有没有办法可以将数据库的回复分成几块?像:

User::chunk(200)->all(); /*which obviously does not work*/

如果我直接通过phpMyAdmin向数据库写一个看似复杂的查询,它将在0.0045秒内返回37035行。 (我怀疑xampp或其他东西在这里有一些优势)

2 个答案:

答案 0 :(得分:1)

        DB::table("table")
            ->select('column1', 'column2')
            ->orderBy('column2', 'asc')
            ->chunk(70000, function($users) {
            foreach ($users as $row) {
              // To do with data
           }
       }

答案 1 :(得分:0)

注意:我将此作为答案发布,因为它涉及一些代码。我想我在原始问题中完全错过了你的观点,因为我试图将整个结果集返回给客户端。如果我还在遗漏某些内容,请发表评论,我将删除此答案。

  

所以我想拿一组对象,用它们做东西并将它们保存回DB

这很简单!

$chunkSize = 100; // or whatever your memory allows
$totalUsers = User::count();

$chunks = floor($totalUsers / $chunkSize);

for ($chunk = 0; $chunk <= $chunks; $chunk++) {

    $offset = $chunk * $chunkSize;

    $users = User::skip($offset)->take($chunkSize)->get();

    foreach($users as $user)
    {
        // do something

        $user->save();
    }
}

如果花费太长时间,如果从HTTP触发此循环,则可能会超时,因此您应该从控制台运行它。