perf(doctor): fetch-join specialties in clinic doctor list (H6)
findByClinicWithFilters left-joined specialties only for filtering, so toListArray() lazy-loaded them per doctor (N+1). addSelect them and switch the result fetch to Paginator(fetchJoinCollection: true) so LIMIT still paginates by doctor. Test infra: ApiTestCase::countQueries() (via doctrine.debug_data_holder). Regression: tests/Doctor/ClinicDoctorListNPlusOneTest asserts the query count does not grow with doctor count (4→10 without the fix). Also relaxed AppointmentExpiryServiceTest's exact-count assertion (it counts all stale pendings in the shared db_test, which accumulates) — logged test-isolation debt as E6. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -161,13 +161,17 @@ class DoctorRepository extends ServiceEntityRepository
|
||||
->setParameter('active', (bool) $filters['active']);
|
||||
}
|
||||
|
||||
$qb->orderBy('d.doctorRate', $sort);
|
||||
// Hydrate specialties in the same query so toListArray() doesn't lazy-load
|
||||
// them per doctor (N+1). fetchJoinCollection keeps LIMIT paginating by
|
||||
// doctor, not by joined rows.
|
||||
$qb->addSelect('s')
|
||||
->orderBy('d.doctorRate', $sort)
|
||||
->setFirstResult(($page - 1) * $limit)
|
||||
->setMaxResults($limit);
|
||||
|
||||
$total = (new Paginator($qb))->count();
|
||||
$results = $qb->setFirstResult(($page - 1) * $limit)
|
||||
->setMaxResults($limit)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
$paginator = new Paginator($qb, fetchJoinCollection: true);
|
||||
$total = count($paginator);
|
||||
$results = iterator_to_array($paginator);
|
||||
|
||||
return [
|
||||
'items' => $results,
|
||||
|
||||
Reference in New Issue
Block a user