Improved performance on query that returns the list of visits for a short URL

This commit is contained in:
Alejandro Celaya 2020-05-02 22:47:59 +02:00
parent 6c30fc73ee
commit 80d41db901

View file

@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\Core\Repository;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Entity\Visit;
class VisitRepository extends EntityRepository implements VisitRepositoryInterface class VisitRepository extends EntityRepository implements VisitRepositoryInterface
@ -82,15 +83,11 @@ class VisitRepository extends EntityRepository implements VisitRepositoryInterfa
?int $offset = null ?int $offset = null
): array { ): array {
$qb = $this->createVisitsByShortCodeQueryBuilder($shortCode, $domain, $dateRange); $qb = $this->createVisitsByShortCodeQueryBuilder($shortCode, $domain, $dateRange);
$qb->select('v') $qb->select('v', 'vl')
->orderBy('v.date', 'DESC'); ->leftJoin('v.visitLocation', 'vl')
->orderBy('v.id', 'DESC')
if ($limit !== null) { ->setMaxResults($limit)
$qb->setMaxResults($limit); ->setFirstResult($offset);
}
if ($offset !== null) {
$qb->setFirstResult($offset);
}
return $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
} }
@ -108,20 +105,14 @@ class VisitRepository extends EntityRepository implements VisitRepositoryInterfa
?string $domain, ?string $domain,
?DateRange $dateRange ?DateRange $dateRange
): QueryBuilder { ): QueryBuilder {
/** @var ShortUrlRepositoryInterface $shortUrlRepo */
$shortUrlRepo = $this->getEntityManager()->getRepository(ShortUrl::class);
$shortUrl = $shortUrlRepo->findOne($shortCode, $domain) ?? -1;
$qb = $this->getEntityManager()->createQueryBuilder(); $qb = $this->getEntityManager()->createQueryBuilder();
$qb->from(Visit::class, 'v') $qb->from(Visit::class, 'v')
->join('v.shortUrl', 'su') ->where($qb->expr()->eq('v.shortUrl', ':shortUrl'))
->where($qb->expr()->eq('su.shortCode', ':shortCode')) ->setParameter('shortUrl', $shortUrl);
->setParameter('shortCode', $shortCode);
// Apply domain filtering
if ($domain !== null) {
$qb->join('su.domain', 'd')
->andWhere($qb->expr()->eq('d.authority', ':domain'))
->setParameter('domain', $domain);
} else {
$qb->andWhere($qb->expr()->isNull('su.domain'));
}
// Apply date range filtering // Apply date range filtering
if ($dateRange !== null && $dateRange->getStartDate() !== null) { if ($dateRange !== null && $dateRange->getStartDate() !== null) {