I'm on Amazon RDS xxlarge with plenty of RAM. The issue is how Eloquent does its query for whereHas(). it does a full table scan on the model that calls it. Our table was 21.5 million rows, I could go pop popcorn, eat it and come back and the query would still be running...
$channel = Channel::find(1); // 21.5 million rows in table
$videos = $channel->whereHas('videos', function($query) {
$query->where('status', 1); // << should only be 1300 videos back. :/
})->get();
If we ran EXPLAIN on the query that hangs
EXPLAIN select * from `channel`
where exists (select * from `video` inner join `channel_video` on `video`.`id` = `channel_video`.`video_id` where `channel`.`id` = `channel_video`.`channel_id` and `status` = 1)
We saw where it is doing a full table lookup on Channel.
So on the Videos model we just added an Anonymous scope builder.
class Channels extends Model
{
public function videos()
{
return $this->belongsToMany(Videos::class, 'channel_video', 'channel_id', 'video_id');
}
}
class Videos extends Model
{
protected static function boot()
{
parent::boot();
static::addGlobalScope('live', function (Builder $builder) {
$builder->where('status', 1); // Speed up the belongsToMany!!!
});
}
}
$channel = Channel::find(1); // 21.5 million rows in table
$videos = $channel->videos()->get(); // fast belongsToMany :D