From 99eb4c2594a8046e85c23b690416a0d296831b0b Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Thu, 30 Apr 2026 16:13:35 +0330 Subject: [PATCH] perf(db): add targeted composite indexes --- .../0003_project_project_ws_arch_upd_idx.py | 21 ++++++++++++++++++ apps/projects/models.py | 1 + ..._timeentry_time_entry_ws_user_start_idx.py | 22 +++++++++++++++++++ apps/time_entries/models.py | 15 +++++++------ ...embership_membership_ws_active_user_idx.py | 19 ++++++++++++++++ apps/workspaces/models.py | 1 + 6 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 apps/projects/migrations/0003_project_project_ws_arch_upd_idx.py create mode 100644 apps/time_entries/migrations/0002_timeentry_time_entry_ws_user_start_idx.py create mode 100644 apps/workspaces/migrations/0007_workspacemembership_membership_ws_active_user_idx.py diff --git a/apps/projects/migrations/0003_project_project_ws_arch_upd_idx.py b/apps/projects/migrations/0003_project_project_ws_arch_upd_idx.py new file mode 100644 index 0000000..b399d6c --- /dev/null +++ b/apps/projects/migrations/0003_project_project_ws_arch_upd_idx.py @@ -0,0 +1,21 @@ +# Generated by Django 5.2.12 on 2026-04-30 12:23 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('clients', '0001_initial'), + ('projects', '0002_remove_projectmembership'), + ('workspaces', '0007_workspacemembership_membership_ws_active_user_idx'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddIndex( + model_name='project', + index=models.Index(fields=['workspace', 'is_archived', 'updated_at'], name='project_ws_arch_upd_idx'), + ), + ] diff --git a/apps/projects/models.py b/apps/projects/models.py index c796310..8b3e8e9 100644 --- a/apps/projects/models.py +++ b/apps/projects/models.py @@ -37,6 +37,7 @@ class Project(BaseModel): ordering = ("-updated_at", "-created_at") indexes = [ models.Index(fields=["workspace"], name="project_workspace_idx"), + models.Index(fields=["workspace", "is_archived", "updated_at"], name="project_ws_arch_upd_idx"), ] constraints = [ models.UniqueConstraint( diff --git a/apps/time_entries/migrations/0002_timeentry_time_entry_ws_user_start_idx.py b/apps/time_entries/migrations/0002_timeentry_time_entry_ws_user_start_idx.py new file mode 100644 index 0000000..5e4f792 --- /dev/null +++ b/apps/time_entries/migrations/0002_timeentry_time_entry_ws_user_start_idx.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.12 on 2026-04-30 12:23 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0003_project_project_ws_arch_upd_idx'), + ('tags', '0001_initial'), + ('time_entries', '0001_initial'), + ('workspaces', '0007_workspacemembership_membership_ws_active_user_idx'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddIndex( + model_name='timeentry', + index=models.Index(fields=['workspace', 'user', 'start_time'], name='time_entry_ws_user_start_idx'), + ), + ] diff --git a/apps/time_entries/models.py b/apps/time_entries/models.py index edacf37..e30d8c1 100644 --- a/apps/time_entries/models.py +++ b/apps/time_entries/models.py @@ -56,13 +56,14 @@ class TimeEntry(BaseModel): class Meta: db_table = "time_entry" ordering = ("-updated_at", "-created_at") - indexes = [ - models.Index(fields=["workspace"], name="time_entry_workspace_idx"), - models.Index(fields=["user"], name="time_entry_user_idx"), - models.Index(fields=["project"], name="time_entry_project_idx"), - models.Index(fields=["start_time"], name="time_entry_start_idx"), - models.Index(fields=["workspace", "start_time"], name="time_entry_workspace_start_idx"), - ] + indexes = [ + models.Index(fields=["workspace"], name="time_entry_workspace_idx"), + models.Index(fields=["user"], name="time_entry_user_idx"), + models.Index(fields=["project"], name="time_entry_project_idx"), + models.Index(fields=["start_time"], name="time_entry_start_idx"), + models.Index(fields=["workspace", "start_time"], name="time_entry_workspace_start_idx"), + models.Index(fields=["workspace", "user", "start_time"], name="time_entry_ws_user_start_idx"), + ] constraints = [ models.UniqueConstraint( fields=["workspace", "user"], diff --git a/apps/workspaces/migrations/0007_workspacemembership_membership_ws_active_user_idx.py b/apps/workspaces/migrations/0007_workspacemembership_membership_ws_active_user_idx.py new file mode 100644 index 0000000..ed01b03 --- /dev/null +++ b/apps/workspaces/migrations/0007_workspacemembership_membership_ws_active_user_idx.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2.12 on 2026-04-30 12:23 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('workspaces', '0006_workspace_thumbnail'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddIndex( + model_name='workspacemembership', + index=models.Index(fields=['workspace', 'is_active', 'user'], name='membership_ws_active_user_idx'), + ), + ] diff --git a/apps/workspaces/models.py b/apps/workspaces/models.py index 77ccc1f..aa5583d 100644 --- a/apps/workspaces/models.py +++ b/apps/workspaces/models.py @@ -80,6 +80,7 @@ class WorkspaceMembership(BaseModel): indexes = [ models.Index(fields=["workspace"], name="membership_workspace_idx"), models.Index(fields=["user"], name="membership_user_idx"), + models.Index(fields=["workspace", "is_active", "user"], name="membership_ws_active_user_idx"), ] constraints = [ models.UniqueConstraint(