So I am doing a simple join and where/orwhere query,
I am trying to get friends and followers statuses:
$statuses = $this
->timeline
->select('timeline.*')
->friendsAndFollowers()
->orderBy('timeline.created_at', 'desc')
->paginate(10);
the methods friendAndFollowers returns a builder query:
/**
* Scope a query to friends and followers statuses.
*
* @param \Illuminate\Database\Eloquent\Builder $query
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeFriendsAndFollowers(Builder $query): Builder
{
return $query
->leftJoin('followables', function ($join) {
$join
->on('timeline.owner_id', '=', 'followables.followable_id')
->on('timeline.owner_type', '=', 'followables.followable_type');
})
->leftJoin('friendships', function ($join) {
$join
->on('timeline.owner_id', '=', 'friendships.recipient_id');
})
->where(function ($query) {
$query
->where('followables.user_id', auth()->user()->id, 'and')
->where('privacy', 'public')
->orWhere('privacy', 'private');
})
->Orwhere(function ($query) {
$query
->where(function ($query) {
$query
->where('friendships.sender_id', Auth::user()->id)
->orWhere('friendships.recipient_id', Auth::user()->id);
})
->where('privacy', 'public')
->orWhere('privacy', 'private');
})
->orWhere(function ($query) {
$query
->where('timeline.owner_id', 1)
->where('timeline.owner_type', User::class);
});
}
The database structure:
Friendships table:
Schema::create(config('friendships.tables.fr_pivot'), function (Blueprint $table) {
$table->increments('id');
$table->morphs('sender');
$table->morphs('recipient');
$table->tinyInteger('status')->default(0);
$table->timestamps();
});
Followers table:
Schema::create(config('follow.followable_table', 'followables'), function (Blueprint $table) {
$table->unsignedInteger('user_id');
$table->unsignedInteger('followable_id');
$table->string('followable_type')->index();
$table->string('relation')->default('follow')->comment('folllow/like/subscribe/favorite/');
$table->timestamp('created_at');
$table->foreign('user_id')
->references(config('follow.users_table_primary_key', 'id'))
->on(config('follow.users_table_name', 'users'))
->onUpdate('cascade')
->onDelete('cascade');
});
Timeline table
Schema::create('timeline', function (Blueprint $table) {
$table->increments('id');
$table->text('status')->nullable();
$table->string('location')->nullable();
$table->string('type')->nullable();
$table->string('privacy')->default('public');
$table->integer('owner_id');
$table->string('owner_type');
$table->timestamps();
$table->softDeletes();
});
Raw sql
SELECT `timeline`.*
FROM `timeline`
LEFT JOIN `followables`
ON `timeline`.`owner_id` = `followables`.`followable_id`
AND `timeline`.`owner_type` = `followables`.`followable_type`
LEFT JOIN `friendships`
ON `timeline`.`owner_id` = `friendships`.`recipient_id`
WHERE ( ( `followables`.`user_id` = ?
AND `privacy` = ?
OR `privacy` = ? )
OR ( ( `friendships`.`sender_id` = ?
OR `friendships`.`recipient_id` = ? )
AND `privacy` = ?
OR `privacy` = ? )
OR ( `timeline`.`owner_id` = ?
AND `timeline`.`owner_type` = ? ) )
When I remove the last orWhere, it seems to speed it up, by a second or 2, when I remove all of it, it speeds up by 3 seconds (the query takes 4 seconds) which is far too much for a simple query, what do I seem to be doing wrong?
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire