我有一个laravel5.6应用程序,列出页面上的项目,同时收集视图。生成页面平均耗时8秒。
表项
CREATE TABLE IF NOT EXISTS items (
id INT AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
views INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
表项\每日\视图
CREATE TABLE IF NOT EXISTS items_daily_views (
id INT AUTO_INCREMENT,
item_id INT NOT NULL,
date DATE NOT NULL,
views INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
模型项
class Item extends Model{
protected $table='items';
}
模型项每日视图
class ItemDailyViews extends Model{
protected $table='items_daily_views';
}
家庭控制器.php
$itemList = Item::orderBy('id','desc')->take(100)->get();
foreach($itemList as $item){
//increment to items
$each=Item::find($item->id);
$each->increment('views');
//increment to items_daily_views
$each=ItemDailyViews::updateOrCreate(
['item_id'=>$item->id,
'date'=>Carbon::now()->format('Y-m-d')]
);
$each->increment('views');
}
return view('home',['itemList',$itemList]);
这个页面大约有200个更新查询,生成这个页面需要8秒钟。这个应用程序的前一个版本使用纯php而不使用laravel,并且使用大约10毫秒来生成(也大大减少了ram)。我一定是做错了什么。请帮忙。谢谢!
3条答案
按热度按时间m0rkklqb1#
如果你有适当的雄辩的关系,这将起作用。
unftdfkk2#
想法
可能不是在laravel中做的雄辩,而是尝试使用发送原始sql查询
DB::statement("UPDATE ...")
它一次更新数据库中所有已查看的行(在我从head写入的sql下面-test it(can contains bug)):你可以用
WHERE
子句来选择要更新的正确行。并采用类似的工作台机构items_daily_views
(这有点复杂,因为首先应该检查给定日期的正确行是否存在(如果不存在则创建),然后更新其视图计数器)。在这种技术中,您应该能够避免从php向db发送超过200个sql单独的查询(并且只发送很少的查询)。vsmadaxz3#
试试这个: