Php Laravel数据库优化
我有一段代码,它从外部API获取数据,然后提交给DB: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
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。