在我的laravel项目中,我正在用数据库种子做一些测试,以检查许多数据库条目的性能。在我的项目中,我有一个模型FlightView,通过protected $table = 'view_flights';
使用SQL视图作为数据库。
在测试过程中,我意识到像FlightView::where('aircraft_id',1)->get()
这样的查询变得非常慢(每次调用2或2.5秒),我正在用Laravel Debugbar评估laravel中的查询运行时。
我意识到,在过滤一个飞机ID时,底层查询的处理方式不同(运行时间2到2.5秒),但是当过滤两个或多个飞行器id时非常快(运行时间大约100毫秒)。通过检查底层视图查询,我做了一些优化,将LEFT JOIN替换为INNER JOIN,以便在两种情况下都使用“ref”(索引查找)(as described here)。
更新视图后,SQL编辑器中的运行时间变为50到100毫秒。然而,在laravel中,使用完全相同的查询仍然非常长:
FlightView::where('aircraft_id',1)->get()
Runtime: 2.23 sec
Query: select * from `view_flights` where `aircraft_id` = 1
我尝试了很多变化,你可以在下面的结果中看到,但我没有得到一个线索是什么出了问题,或者我可以做什么下一步...
FlightView::whereIn('aircraft_id',[1])->get()
Runtime: 2.24 sec
Query: select * from `view_flights` where `aircraft_id` in (1)
为了排除任何雄辩的问题,我尝试了同样的DB外观,但它仍然很慢。
DB::table('view_flights')->where('aircraft_id',1)->get()
Runtime: 2.22 sec
Query: select * from `view_flights` where `aircraft_id` = 1
接下来我尝试了DB::select()
语句,但也没有改进:
DB::select('select * from view_flights where aircraft_id=?',[1]);
Runtime: 2.22 sec
Query: select * from `view_flights` where `aircraft_id` = 1
如果没有绑定,查询速度会大大提高:接下来我尝试了DB::select()
语句,但也没有改进:
DB::select('select * from view_flights where aircraft_id=1');
Runtime: 23 ms
Query: select * from view_flights where aircraft_id = 1
令人惊讶的是,当过滤两个飞机id时,laravel查询仍然非常快:
FlightView::whereIn('aircraft_id',[1,2])->get()
Runtime: 53 ms
Query: select * from `view_flights` where `aircraft_id` in (1,2)
接下来,我让拉拉威尔试着解释一下,为什么它这么慢:
DB::select('explain select * from view_flights where aircraft_id=?',[1]);
Runtime: 2.22 sec
Query: explain select * from `view_flights` where `aircraft_id` = 1
因此Laravel似乎仍然采用“慢”查询方法,而不是“ref”(索引查找)方法:-(
推测/开放性问题?
- 这个问题是laravel特有的还是SQL特有的?
- 是否有任何MySQL设置,这可能会导致不同的行为?
- 可能是什么原因,laravel处理的查询与我的sql编辑器不同?
- 是否有相同类型的“SQL视图”-缓存或在Laravel中,可能仍然使用旧版本的视图?
- laravel内部有没有什么“魔法”可以解释这种行为?
- 接下来我该怎么办?
2条答案
按热度按时间8dtrkrch1#
我会给予你一些建议。
我希望它能帮助你解决优化问题。
izj3ouym2#
aircraft_id
的数据类型是什么?如果是VARCHAR
,那么问题出在对一个数字进行测试上。将1
更改为"1"
。这样,它会在测试前将每行的aircraft_id转换为字符串。(That建议也适用于您的
IN
等。)而且,确实有
INDEX(aircraft_id)
。