Laravel多次更新慢

时间:2018-11-18 15:00:27

标签: mysql laravel laravel-5.6

我有一个laravel 5.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;

表items_daily_views

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';
}

模型ItemDailyViews

class ItemDailyViews extends Model{
  protected $table='items_daily_views';
}

HomeController.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秒钟来生成。该应用程序的旧版本使用不带laravel的纯PHP,并使用大约10毫秒来生成(也显着减少了RAM)。我一定做错了。请帮忙。谢谢!

3 个答案:

答案 0 :(得分:1)

想法

可能不是用雄辩的方法,而是尝试使用DB::statement("UPDATE ...")发送原始SQL查询,该查询会一次更新DB内部的所有已查看行(在我写自头的sql下面-测试它(可能包含错误) ):

UPDATE items
    SET views = views + 1
    ORDER BY id DESC
    LIMIT 100;

您可以使用WHERE子句来选择要更新的适当行。并对表items_daily_views使用类似的机制(稍微复杂一点,因为首先应检查给定日期的正确行是否存在(create if not),然后更新其视图计数器)。使用这种技术,您应该能够避免从php向DB发送超过200个sql单独的查询(并且仅发送少量查询)。

答案 1 :(得分:1)

尝试一下:

fit <- cforest(as.factor(Job.Scope) ~ Date + Hour + Item,
               data = tt_10,
               controls=cforest_unbiased(ntree=2000,mtry=3))

fit <- randomForest(as.factor(Job.Scope) ~ Date + Hour +Item,
                    data=tt_10,
                    importance=TRUE,
                    ntree=2000)

fit <- rpart(Job.Scope ~ Date + Hour + Item, method="class", data=TrainData,
             control=rpart.control(minsplit=1))

答案 2 :(得分:1)

$itemList = Item::orderBy('id','desc')->take(100)->get();
$itemDailyViews=[];
foreach($itemList as $item){
   //increment to items
   $item->itemDailyViews->date = Carbon::now()->format('Y-m-d');
   $item->itemDailyViews->increment('views');
   array_push($itemDailyViews,$item->itemDailyViews);

}
$itemList->itemDailyViews()->saveMany($itemDailyViews);
return view('home',['itemList',$itemList]);

如果您已赋予适当的口才,这将起作用。