Skip to content

Commit

Permalink
Take N^2+1 queries down to N+1 via custom leaderboard query
Browse files Browse the repository at this point in the history
  • Loading branch information
iansltx committed Mar 7, 2019
1 parent 29cc1fe commit a842cb3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 19 deletions.
29 changes: 13 additions & 16 deletions app/Challenge.php
Expand Up @@ -2,6 +2,7 @@

namespace Challengr;

use Challengr\Query\ChallengeStats;
use Illuminate\Database\Eloquent\Model;

/**
Expand Down Expand Up @@ -62,17 +63,15 @@ public function getLeaderboard()

public function getDurationLeaderboard()
{
$arr = $this->users_joined->map(function(User $user) {
$stats = ChallengeStats::getForChallenge($this->id);

$arr = $this->users_joined->map(function(User $user) use ($stats) {
return [
'id' => $user->id,
'name' => $user->name,
'duration_seconds' => $durationInSeconds = $user->activities()
->whereBetween('started_at', [$this->starts_at, $this->ends_at])
->sum('duration'),
'distance_miles' => $user->activities()
->whereBetween('started_at', [$this->starts_at, $this->ends_at])
->sum('distance_miles'),
'duration' => Util::secondsToTime($durationInSeconds),
'duration_seconds' => $stats[$user->id]['duration'] ?? 0,
'distance_miles' => $stats[$user->id]['distance_miles'] ?? 0,
'duration' => Util::secondsToTime($stats[$user->id]['duration'] ?? 0),
];
})->toArray();
usort($arr, function ($a, $b) {
Expand All @@ -83,17 +82,15 @@ public function getDurationLeaderboard()

public function getDistanceLeaderboard()
{
$arr = $this->users_joined->map(function(User $user) {
$stats = ChallengeStats::getForChallenge($this->id);

$arr = $this->users_joined->map(function(User $user) use ($stats) {
return [
'id' => $user->id,
'name' => $user->name,
'duration_seconds' => $durationInSeconds = $user->activities()
->whereBetween('started_at', [$this->starts_at, $this->ends_at])
->sum('duration'),
'distance_miles' => $user->activities()
->whereBetween('started_at', [$this->starts_at, $this->ends_at])
->sum('distance_miles'),
'duration' => Util::secondsToTime($durationInSeconds),
'duration_seconds' => $stats[$user->id]['duration'] ?? 0,
'distance_miles' => $stats[$user->id]['distance_miles'] ?? 0,
'duration' => Util::secondsToTime($stats[$user->id]['duration'] ?? 0),
];
})->toArray();
usort($arr, function ($a, $b) {
Expand Down
8 changes: 5 additions & 3 deletions app/Http/Controllers/ChallengeController.php
Expand Up @@ -15,9 +15,11 @@ class ChallengeController extends Controller
public function forCurrentUser(Request $request)
{
return [
'created' => Challenge::whereUserId($userId = $request->user()->id)->orderByDesc('created_at')->get(),
'joined' => Challenge::whereHas('users_joined', function(Builder $builder) use ($userId) {
return $builder->whereKey($userId);
'created' => Challenge::with('users_joined')
->whereUserId($userId = $request->user()->id)->orderByDesc('created_at')->get(),
'joined' => Challenge::with('users_joined')
->whereHas('users_joined', function(Builder $builder) use ($userId) {
return $builder->whereKey($userId);
})->orderByDesc('ends_at')->get()
];
}
Expand Down
19 changes: 19 additions & 0 deletions app/Query/ChallengeStats.php
@@ -0,0 +1,19 @@
<?php

namespace Challengr\Query;

class ChallengeStats
{
public static function getForChallenge($id)
{
$ret = [];
foreach (\DB::select(' select sum(activities.duration) duration, sum(activities.distance_miles) distance_miles,
activities.user_id from activities join challenge_user on challenge_user.user_id = activities.user_id
join challenges on challenges.id = challenge_user.challenge_id
where activities.started_at between challenges.starts_at and challenges.ends_at && challenges.id = ?
group by activities.user_id', [$id]) as $row) {
$ret[$row->user_id] = ['distance_miles' => $row->distance_miles, 'duration' => $row->duration];
}
return $ret;
}
}

0 comments on commit a842cb3

Please sign in to comment.