What is the query that actually runs from all of that setup?
Do you have an appropriate index on columns that your filters are being applied to?
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I have the following filtering/grouping
public function rows($organizationId, Request $request)
{
if (!$request->has('groupByItems')) {
abort(404);
}
$groupByItems = json_decode($request->get('groupByItems'));
$organization = auth()->user()->availableOrganizations()->findOrFail($organizationId);
$query = PageViewEvent::where('page_view_events.organization_id', $organization->id);
$select = $this->getSelect($groupByItems);
$query->select($select);
$query = $this->filterByPeriod($query, $request);
$query = $this->grouping($query, $groupByItems);
$query = $this->filterRows($query, $groupByItems, $request->input('filters'));
$query = $this->dynamicSort($query, $request);
$rows = $query->get();
return response()->json(
$rows
);
}
PageViewEvent model has 175K rows in database, which makes it really slow to load in front end I need to wait 44 secs for this to load.
All the filtering grouping its done using raw queries due to performance issues. Adding caching in top of this its just soo much hassle since user has a filter by period to filter data so its kind of redundant to some point!
I started even thinking of using elastic search for that model but that will require me to >rewrite the whole logic again!
*Anyone has any suggestion on how to optimize this a little bit more ? *
p.s for instance here is the select method
protected function getSelect($groupByItems)
{
$select = "count({$this->model->getTable()}.id) as count,";
if ($groupByItems->sessionId) {
$select .= 'session_id,';
}
if ($groupByItems->referrer) {
$select .= 'referrer,';
}
if ($groupByItems->trackingCode) {
$select .= 'tracking_codes.code as tracking_code,';
$select .= 'tracking_codes.label as tracking_label,';
}
if ($groupByItems->trackingSource) {
$select .= 'ts.name as tracking_source,';
}
if (isset($groupByItems->path) && $groupByItems->path) {
$select .= 'path,';
}
//if ($groupByItems->senderInfo->platform) {
// $select .= 'senders_info.platform as platform,';
//}
if ($groupByItems->senderInfo->device) {
$select .= 'senders_info.device as device,';
}
if ($groupByItems->senderInfo->os) {
$select .= 'senders_info.os as os,';
}
if ($groupByItems->senderInfo->browser) {
$select .= 'senders_info.browser as browser,';
}
if (!empty($groupByItems->date)) {
$select .= 'day(page_view_events.created_at) as date,';
}
if (!empty($groupByItems->weekday)) {
$select .= 'dayname(page_view_events.created_at) as weekday,';
}
if (!empty($groupByItems->timeofday)) {
$select .= 'hour(page_view_events.created_at) as timeofday,';
}
if (!empty($groupByItems->month)) {
$select .= 'monthname(page_view_events.created_at) as month,';
}
$select .= $this->customSelectFields;
return DB::raw(rtrim($select, ","));
}
Same goes for grouping it uses raw db queries
Any help would be welcomed.
Please or to participate in this conversation.