Fix performance issue of PageviewsPerDay widget

Issue a single query with native group by instead of x queries.

Resolves: #63
This commit is contained in:
Daniel Siepmann 2021-08-03 11:08:12 +02:00
parent 9624847b9a
commit 67c2d22f15
2 changed files with 31 additions and 15 deletions

View file

@ -101,21 +101,26 @@ class PageviewsPerDay implements ChartDataProviderInterface
$data = []; $data = [];
for ($daysBefore = $this->days; $daysBefore >= 0; $daysBefore--) { for ($daysBefore = $this->days; $daysBefore >= 0; $daysBefore--) {
$timeForLabel = (int) strtotime('-' . $daysBefore . ' day'); $label = date($this->dateFormat, (int) strtotime('-' . $daysBefore . ' day'));
$startPeriod = (int) strtotime('-' . $daysBefore . ' day 0:00:00'); $labels[$label] = $label;
$endPeriod = (int) strtotime('-' . $daysBefore . ' day 23:59:59'); $data[$label] = 0;
}
$labels[] = date($this->dateFormat, $timeForLabel); $start = (int) strtotime('-' . $this->days . ' day 0:00:00');
$data[] = $this->getPageviewsInPeriod($startPeriod, $endPeriod); $end = (int) strtotime('tomorrow midnight');
foreach ($this->getPageviewsInPeriod($start, $end) as $day) {
$data[$day['label']] = (int) $day['count'];
} }
return [ return [
$labels, array_values($labels),
$data, array_values($data),
]; ];
} }
private function getPageviewsInPeriod(int $start, int $end): int private function getPageviewsInPeriod(int $start, int $end): array
{ {
$constraints = [ $constraints = [
$this->queryBuilder->expr()->gte('crdate', $start), $this->queryBuilder->expr()->gte('crdate', $start),
@ -142,11 +147,20 @@ class PageviewsPerDay implements ChartDataProviderInterface
); );
} }
return (int)$this->queryBuilder $this->queryBuilder
->count('*') ->addSelectLiteral('COUNT(*) as "count"')
->from('tx_tracking_pageview') ->from('tx_tracking_pageview')
->where(...$constraints) ->where(...$constraints)
->execute() ->groupBy('label')
->fetchColumn(); ->orderBy('label', 'ASC')
;
if ($this->queryBuilder->getConnection()->getDatabasePlatform()->getName() === 'sqlite') {
$this->queryBuilder->addSelectLiteral('date(crdate, "unixepoch") as "label"');
} else {
$this->queryBuilder->addSelectLiteral('FROM_UNIXTIME(crdate, "%Y-%m-%d") as "label"');
}
return $this->queryBuilder->execute()->fetchAll();
} }
} }

View file

@ -25,10 +25,12 @@ Fixes
This mainly improves the PageviewsPerPage widget. This mainly improves the PageviewsPerPage widget.
PageviewsPerDay is still way to slow, but I couldn't find a working approach to PageviewsPerDay is fixed by altering the whole query to fetch all data in a
improve performance. performant way.
A single query with native group by date is issued, instead of a single query per
day.
Relates: :issue:`63`. Resolves: :issue:`63`.
Tasks Tasks
----- -----