与 mySQL 相比,Laravel Eloquent 查询运行速度非常慢

问题描述 投票:0回答:1

为什么这个 laravel 雄辩查询运行得这么

我在 Laravel 作业中运行一个查询,该查询执行速度非常慢且不一致。有时需要 1-2 分钟才能获取结果,而有时对于相同的精确查询只需 1-2 秒即可完成。

慢速完整雄辩查询需要1-2分钟才能完成查询

$relevantRobot = App\Robot::where('serial_number', 'TEST-ID')
                    ->whereHas('robot_maps', function($query) use ($robot_map_name) {
                        $query->where('name', $robot_map_name);
                    })
                    ->with(['robot_maps' => function($query) use ($robot_map_name) {
                            $query->where('name', $robot_map_name);
                        },
                        'current_robot_position',
                        'current_robot_position.robot_map',
                        'latest_robot_deployment_information_request'
                    ])
                    ->first(); // Get the raw SQL query

缓慢简化的雄辩查询需要1-2分钟才能完成查询

$relevantRobot = App\Robot::where('serial_number', 'TEST-ID')
                    ->whereHas('robot_maps', function($query) use ($robot_map_name) {
                        $query->where('name', $robot_map_name);
                    })
                    ->with(
                        'current_robot_position',
                    ])
                    ->first(); // Get the raw SQL query

快速简化的雄辩查询不到一秒即可完成

$relevantRobot = App\Robot::where('serial_number', 'TEST-ID')
                    ->whereHas('robot_maps', function($query) use ($robot_map_name) {
                        $query->where('name', $robot_map_name);
                    })
                    ->with(
                        'latest_robot_deployment_information_request',
                    ])
                    ->first(); // Get the raw SQL query

SQL 查询不到一秒即可完成

select * from `robots` where `serial_number` = 'TEST-ID' and exists (select * from `robot_maps` where `robots`.`id` = `robot_maps`.`robot_id` and `name` = 'test' and `active` = 1);

雄辩的关系

 public function current_robot_position(){
        return $this->hasOne('App\RobotMapPositionLog','robot_id','id')
            ->orderBy('id','desc');
    }

尝试的解决方案

在注意到急切加载 current_robot_position 时加载时间较慢后,我向该关系中使用的列(id)添加了索引。然而,这并没有提高性能。

我还尝试使用 toSql() 将 Eloquent 查询转换为原始 MySQL 查询,它运行得非常快(不到 1 秒)。

出了什么问题?我错过了什么?

php mysql laravel eloquent mysql-slow-query-log
1个回答
0
投票

要提高 Laravel 查询的速度,请尝试以下步骤:

  1. 优化关系中的orderBy:使用latest('id')而不是

    orderBy('id', 'desc'): 公共函数 current_robot_position() { return $this->hasOne('App\RobotMapPositionLog', 'robot_id', 'id')->latest('id'); }

  2. 添加索引:确保robot_maps和robot_map_position_logs表中的robot_id列已建立索引。

  3. 使用limit(1):直接在SQL中将主查询限制为一条记录:

    ->limit(1)->first();

  4. 减少嵌套关系加载:分两步加载嵌套关系,以避免额外的查询:

    if ($relevantRobot) { $relevantRobot->load(['current_robot_position', 'current_robot_position.robot_map']); }

  5. 使用缓存:缓存经常访问的查询的结果,以防止重新运行查询:

    Cache::remember('relevantRobot-' . $robot_map_name, now()->addMinutes(10), function() { ... });

© www.soinside.com 2019 - 2024. All rights reserved.