Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Laravel数据库优化_Php_Mysql_Performance_Laravel - Fatal编程技术网

Php Laravel数据库优化

Php Laravel数据库优化,php,mysql,performance,laravel,Php,Mysql,Performance,Laravel,我有一段代码,它从外部API获取数据,然后提交给DB: protected function saveWidgetsToDatabase($widgetsDaily, Boost $boost, $date) { echo "Saving widgets to DB... "; $widgets = Widget::all(); foreach ($widgetsDaily as $widgetDaily) { $existingWidget = $wi

我有一段代码,它从外部API获取数据,然后提交给DB:

protected function saveWidgetsToDatabase($widgetsDaily, Boost $boost, $date)
{
    echo "Saving widgets to DB... ";

    $widgets = Widget::all();
    foreach ($widgetsDaily as $widgetDaily) {
        $existingWidget = $widgets
            ->where('widget_id', $widgetDaily->id)
            ->where('date', $date)
            ->first();

        if ($existingWidget === null)
            $boost->widgets()->save(new Widget([
               ...
            ]));
        else
            $existingWidget->update([
                ...
            ]);
    }
}
我的关系是一个Boost有很多小部件。现在,我面临的问题是数据库保存/更新的瓶颈,因为我只需要更新具有相同日期和ID的小部件,否则我需要创建一个新的小部件

我们讨论的是几千条记录,所以我认为where子句非常密集

我想进行批量保存,尽管我没有完全做到

有没有可能使这个过程更快?

当您调用Widget::all;,它获取数据库中的每个小部件记录,并为其创建一个小部件实例。因此,$widgets将是存储在数据库中的每个Widget对象的集合。如果您有10000个小部件记录,那么您将拥有10000个小部件对象的集合。这显然不是你想要的

这也意味着,当您调用$widgets->where…,您调用的是集合对象上的where,它使用PHP过滤对象集合,而不是使用SQL过滤数据库结果

你可以做几件事

首先,你知道你只关心那些id在$widgetsday列表中的小部件。因此,将小部件查询限制为仅包括id列表中具有小部件id的记录

其次,还要将日期查找添加到数据库查询中

第三,通过widget_id字段输入结果集合,这样您就可以通过widget_id直接访问该项,而无需每次在整个集合中循环查找它

protected function saveWidgetsToDatabase($widgetsDaily, Boost $boost, $date)
{
    // Get the only widget_ids we care about (assumes $widgetsDaily is a collection)
    $ids = $widgetsDaily->pluck('id')->all();

    // Get the target widgets from the database. This collection will only
    // contain widgets that we actually care about.
    $widgets = Widget::whereIn('widget_id', $ids)
        ->where('date', $date)
        ->get()
        ->keyBy('widget_id'); // rekey the resulting collection

    foreach ($widgetsDaily as $widgetDaily) {
        // Because the collection was rekeyed on widget_id, you can use
        // get(id) instead of having to use where('widget_id', id)->first()
        $existingWidget = $widgets->get($widgetDaily->id);

        if ($existingWidget === null)
            $boost->widgets()->save(new Widget([
               ...
            ]));
        else
            $existingWidget->update([
                ...
            ]);
    }
}

你有小部件id和日期索引吗?不,不是真的…那会有帮助吗?是的。索引有助于数据库更快地查找信息,并加快where查询。请提供生成的SQL。