Php Laravel控制器功能超时,50000用户

Php Laravel控制器功能超时,50000用户,php,laravel,eloquent,Php,Laravel,Eloquent,在我的控制器中,我有一个功能来检查订阅状态并在数据库中更新它。问题是有50000个用户,完成时间太长,超时 public function UpdateStatus(){ $users = User::all(); foreach($users as $user){ $user->createOrGetStripeCustomer(); $stripeSubs = $user->asStripeCustomer()->subsc

在我的控制器中,我有一个功能来检查订阅状态并在数据库中更新它。问题是有50000个用户,完成时间太长,超时

public function UpdateStatus(){
    $users = User::all();

    foreach($users as $user){
        $user->createOrGetStripeCustomer();
        $stripeSubs = $user->asStripeCustomer()->subscriptions->all();
        $dbSubs = DB::table('subscriptions')->select('stripe_id')->where('user_id', $user->id)->get();
        foreach($dbSubs as $check){
            $canDelete=0;
            foreach($stripeSubs as $value){
                if($check->stripe_id == $value->id){
                    $canDelete++;
                }
            }


            if($canDelete==0){
                DB::table('subscriptions')->where('user_id', $user->id)->where('stripe_id',$check->stripe_id)->update(['stripe_status'=>'ended']);
            }
        }
        
    }
    
    return redirect('/dashboard');
}  

我确信我甚至不应该一次处理那么多,但我有点被困在这里,不知道如何准确地处理这个问题。我的目标是让它工作并优化它。

首先,您应该在队列作业中执行此操作:
这样脚本就不会超时

然而,将50k有说服力的对象加载到内存中并不是最佳选择。要解决此问题,可以使用惰性集合:

这将只执行一个查询,但将只在内存中保留一个
用户对象。

您使用的作业如下:

php artisan make:job checkSubscrption
在环境文件中,更改队列连接=数据库, 运行
php artisan队列:表
php artisan迁移
在您的checkSubscription文件中设置

public function handle(){
            $users = User::all();
  
foreach($users as $user){
    $user->createOrGetStripeCustomer();
    $stripeSubs = $user->asStripeCustomer()->subscriptions->all();
    $dbSubs = DB::table('subscriptions')->select('stripe_id')->where('user_id', $user->id)->get();
    foreach($dbSubs as $check){
        $canDelete=0;
        foreach($stripeSubs as $value){
            if($check->stripe_id == $value->id){
                $canDelete++;
            }
        }


        if($canDelete==0){
            DB::table('subscriptions')->where('user_id', $user->id)->where('stripe_id',$check->stripe_id)->update(['stripe_status'=>'ended']);
        }
    }
    
}}
在控制器中:

public function UpdateStatus(){

 checkSubscrption::dispatch();//you can use chunk method and pass your $users as params
 return redirect('/dashboard');}

然后运行
php artisan queue:work

让它成为一个队列作业,在后台运行可能会有所帮助?
public function UpdateStatus(){

 checkSubscrption::dispatch();//you can use chunk method and pass your $users as params
 return redirect('/dashboard');}