Perf: customer press-releases-Liste ueber UNION statt OR-Paginate
Die Uebersicht /admin/me/press-releases war auch fuer leere Konten ~2s: der OR-Filter in scopeAccessibleBy zwang die Paginator-count(*) zum Full-Scan (EXPLAIN type=ALL, ~174k Zeilen) und den Zeilen-Fetch bei 0 Treffern zum vollen created_at-Index-Scan (~1s). Neue PressRelease::accessiblePageFor() nutzt dieselbe index-freundliche UNION wie accessibleStatusCountsFor(): schmale UNION liefert die Seiten-IDs ueber user_id-/company_id-Index, danach nur 25 Modelle hydratisiert; Total via schnellem UNION-count. Messung: leer ~2000ms -> 167ms, groesstes Konto (20.830 PMs) ~740ms -> 468ms. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
90f3245e41
commit
db7c1dfbf1
3 changed files with 164 additions and 11 deletions
|
|
@ -135,17 +135,16 @@ new #[Layout('components.layouts.app'), Title('Meine Pressemitteilungen')] class
|
|||
PressReleaseStatus::Archived->value => $statusCountsRaw[PressReleaseStatus::Archived->value] ?? 0,
|
||||
];
|
||||
|
||||
$prs = PressRelease::accessibleBy($user)
|
||||
->tap($applyCompanyFilter)
|
||||
->with('company:id,name')
|
||||
->when(filled($this->search), function ($q): void {
|
||||
$term = $this->search;
|
||||
$q->where('title', 'like', '%' . $term . '%');
|
||||
})
|
||||
->when($this->statusFilter !== 'all', fn($q) => $q->where('status', $this->statusFilter))
|
||||
->when($this->portalFilter !== 'all', fn($q) => $q->where('portal', $this->portalFilter))
|
||||
->orderBy(in_array($this->sortBy, ['title', 'status', 'created_at']) ? $this->sortBy : 'created_at', $this->sortDir)
|
||||
->paginate(25);
|
||||
// Der Firmen-Scope plus die Suchleiste/Status-/Portal-Filter werden in
|
||||
// beide UNION-Zweige gezogen (siehe PressRelease::accessiblePageFor()).
|
||||
$applyListFilters = function ($query) use ($applyCompanyFilter): void {
|
||||
$applyCompanyFilter($query);
|
||||
$query->when(filled($this->search), fn ($q) => $q->where('title', 'like', '%'.$this->search.'%'))
|
||||
->when($this->statusFilter !== 'all', fn ($q) => $q->where('status', $this->statusFilter))
|
||||
->when($this->portalFilter !== 'all', fn ($q) => $q->where('portal', $this->portalFilter));
|
||||
};
|
||||
|
||||
$prs = PressRelease::accessiblePageFor($user, $applyListFilters, $this->sortBy, $this->sortDir);
|
||||
|
||||
return [
|
||||
'pressReleases' => $prs,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue