From 8b96753df67063cc8e34710705688b575c7bda7a Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Sun, 28 Jun 2026 17:13:44 +0330 Subject: [PATCH] perf(db): add missing indexes (appointment expiry, session dates, user status) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - appointments(status, expires_at): the per-minute expiry scheduler filtered on these with no covering index - patient_sessions(created_at): dashboard revenue range scans - users(status): admin user-list filter PatientRecord(entity_type,entity_id) already covered by its unique constraint; UserActiveContext.user_id is the PK — neither needed a new index. --- migrations/Version20260628134241.php | 33 ++++++++++++++++++++++++++ src/Appointment/Entity/Appointment.php | 1 + src/Auth/Entity/User.php | 1 + src/Patient/Entity/PatientSession.php | 1 + 4 files changed, 36 insertions(+) create mode 100644 migrations/Version20260628134241.php diff --git a/migrations/Version20260628134241.php b/migrations/Version20260628134241.php new file mode 100644 index 00000000..82518d7b --- /dev/null +++ b/migrations/Version20260628134241.php @@ -0,0 +1,33 @@ +addSql('CREATE INDEX idx_appointments_status_expires ON appointments (status, expires_at)'); + $this->addSql('CREATE INDEX idx_patient_sessions_created_at ON patient_sessions (created_at)'); + $this->addSql('CREATE INDEX idx_users_status ON users (status)'); + } + + public function down(Schema $schema): void + { + $this->addSql('DROP INDEX idx_appointments_status_expires ON appointments'); + $this->addSql('DROP INDEX idx_patient_sessions_created_at ON patient_sessions'); + $this->addSql('DROP INDEX idx_users_status ON users'); + } +} diff --git a/src/Appointment/Entity/Appointment.php b/src/Appointment/Entity/Appointment.php index 6d0a1429..cec04ef5 100644 --- a/src/Appointment/Entity/Appointment.php +++ b/src/Appointment/Entity/Appointment.php @@ -12,6 +12,7 @@ use Symfony\Component\Uid\Uuid; #[ORM\Table(name: 'appointments')] #[ORM\Index(columns: ['doctor_id', 'slot_start'], name: 'idx_appointments_doctor_slot')] #[ORM\Index(columns: ['user_id', 'status'], name: 'idx_appointments_user_status')] +#[ORM\Index(columns: ['status', 'expires_at'], name: 'idx_appointments_status_expires')] class Appointment { // Status machine: pending → confirmed → completed diff --git a/src/Auth/Entity/User.php b/src/Auth/Entity/User.php index a36c7b75..7d29139a 100644 --- a/src/Auth/Entity/User.php +++ b/src/Auth/Entity/User.php @@ -11,6 +11,7 @@ use Symfony\Component\Uid\Uuid; #[ORM\Entity(repositoryClass: UserRepository::class)] #[ORM\Table(name: 'users')] #[ORM\UniqueConstraint(name: 'uniq_mobile', columns: ['mobile_number'])] +#[ORM\Index(columns: ['status'], name: 'idx_users_status')] class User implements UserInterface, PasswordAuthenticatedUserInterface { #[ORM\Id] diff --git a/src/Patient/Entity/PatientSession.php b/src/Patient/Entity/PatientSession.php index 28db893f..02b0a89f 100644 --- a/src/Patient/Entity/PatientSession.php +++ b/src/Patient/Entity/PatientSession.php @@ -11,6 +11,7 @@ use Symfony\Component\Uid\Uuid; #[ORM\Entity(repositoryClass: PatientSessionRepository::class)] #[ORM\Table(name: 'patient_sessions')] +#[ORM\Index(columns: ['created_at'], name: 'idx_patient_sessions_created_at')] class PatientSession { #[ORM\Id]