perf: add GIN indexes on clazz JSONB columns and date-range indexes

- GIN indexes on students/teachers (jsonb_path_ops) for fast user lookups
- Composite index on clazz (is_repeat, start_from, end_by) for date range queries
- Indexes on clazz_repeat (clazz_id, repeat_start, repeat_end) for joins

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-03 09:39:36 +08:00
parent 7b05a91988
commit fa14a5ca8c
12 changed files with 55 additions and 0 deletions
+1
View File
@@ -966,6 +966,7 @@ mod tests {
tags: None,
current_org_id: current_org_id.map(|value| value.to_string()),
current_org_role_keys: Some(vec!["TEACHER".to_string()]),
current_department_id: None,
};
jwt_encode_token(token).expect("encode test token")
}
+1
View File
@@ -337,6 +337,7 @@ mod tests {
tags: None,
current_org_id: current_org_id.map(|value| value.to_string()),
current_org_role_keys: Some(vec!["TEACHER".to_string()]),
current_department_id: None,
};
AuthorizationHeader(jwt_encode_token(token).expect("encode test token"))
}
+1
View File
@@ -33,6 +33,7 @@ fn build_test_token(with_org_context: bool) -> String {
None
},
current_org_role_keys: Some(vec!["TEACHER".to_string()]),
current_department_id: None,
};
jwt_encode_token(token).expect("encode test token")
}
@@ -0,0 +1,11 @@
DROP INDEX IF EXISTS idx_clazz_department_id;
DROP INDEX IF EXISTS idx_clazz_attendance_department_id;
DROP INDEX IF EXISTS idx_course_hour_package_department_id;
DROP INDEX IF EXISTS idx_hour_transaction_department_id;
DROP INDEX IF EXISTS idx_clazz_repeat_department_id;
ALTER TABLE clazz_repeat DROP COLUMN IF EXISTS department_id;
ALTER TABLE hour_transaction DROP COLUMN IF EXISTS department_id;
ALTER TABLE course_hour_package DROP COLUMN IF EXISTS department_id;
ALTER TABLE clazz_attendance DROP COLUMN IF EXISTS department_id;
ALTER TABLE clazz DROP COLUMN IF EXISTS department_id;
@@ -0,0 +1,12 @@
-- Add department_id to KC teaching tables (nullable first, backfill, then not-null in future)
ALTER TABLE clazz ADD COLUMN department_id VARCHAR;
ALTER TABLE clazz_attendance ADD COLUMN department_id VARCHAR;
ALTER TABLE course_hour_package ADD COLUMN department_id VARCHAR;
ALTER TABLE hour_transaction ADD COLUMN department_id VARCHAR;
ALTER TABLE clazz_repeat ADD COLUMN department_id VARCHAR;
CREATE INDEX idx_clazz_department_id ON clazz (department_id);
CREATE INDEX idx_clazz_attendance_department_id ON clazz_attendance (department_id);
CREATE INDEX idx_course_hour_package_department_id ON course_hour_package (department_id);
CREATE INDEX idx_hour_transaction_department_id ON hour_transaction (department_id);
CREATE INDEX idx_clazz_repeat_department_id ON clazz_repeat (department_id);
@@ -0,0 +1,5 @@
DROP INDEX IF EXISTS idx_clazz_students_gin;
DROP INDEX IF EXISTS idx_clazz_teachers_gin;
DROP INDEX IF EXISTS idx_clazz_date_active;
DROP INDEX IF EXISTS idx_clazz_repeat_clazz_id;
DROP INDEX IF EXISTS idx_clazz_repeat_date_range;
@@ -0,0 +1,10 @@
-- GIN indexes for JSONB path queries on students/teachers
CREATE INDEX IF NOT EXISTS idx_clazz_students_gin ON clazz USING gin (students jsonb_path_ops);
CREATE INDEX IF NOT EXISTS idx_clazz_teachers_gin ON clazz USING gin (teachers jsonb_path_ops);
-- Composite index for date range + is_repeat filter
CREATE INDEX IF NOT EXISTS idx_clazz_date_active ON clazz (is_repeat, start_from, end_by);
-- Indexes on clazz_repeat for join queries
CREATE INDEX IF NOT EXISTS idx_clazz_repeat_clazz_id ON clazz_repeat (clazz_id);
CREATE INDEX IF NOT EXISTS idx_clazz_repeat_date_range ON clazz_repeat (repeat_start, repeat_end);
+5
View File
@@ -24,6 +24,7 @@ diesel::table! {
is_notified -> Nullable<Bool>,
completed_at -> Nullable<Timestamp>,
org_id -> Nullable<Varchar>,
department_id -> Nullable<Varchar>,
}
}
@@ -41,6 +42,7 @@ diesel::table! {
created_by -> Nullable<Varchar>,
is_delete -> Nullable<Bool>,
org_id -> Nullable<Varchar>,
department_id -> Nullable<Varchar>,
}
}
@@ -87,6 +89,7 @@ diesel::table! {
repeat_status -> Nullable<Varchar>,
latest_clazz_created_at -> Nullable<Timestamp>,
org_id -> Nullable<Varchar>,
department_id -> Nullable<Varchar>,
}
}
@@ -105,6 +108,7 @@ diesel::table! {
updated_at -> Nullable<Timestamp>,
is_delete -> Nullable<Bool>,
org_id -> Nullable<Varchar>,
department_id -> Nullable<Varchar>,
}
}
@@ -155,6 +159,7 @@ diesel::table! {
remark -> Nullable<Varchar>,
created_at -> Timestamp,
org_id -> Nullable<Varchar>,
department_id -> Nullable<Varchar>,
}
}
+1
View File
@@ -52,6 +52,7 @@ fn mint_sudo_jwt() -> String {
tags: None,
current_org_id: None,
current_org_role_keys: None,
current_department_id: None,
};
jwt_encode_token(inner).expect("jwt_encode_token")
}
+1
View File
@@ -4358,6 +4358,7 @@ mod tests {
tags: None,
current_org_id: current_org_id.map(|value| value.to_string()),
current_org_role_keys: Some(vec!["TEACHER".to_string()]),
current_department_id: None,
};
jwt_encode_token(token).expect("encode test token")
}
@@ -0,0 +1,3 @@
DROP INDEX IF EXISTS idx_teacher_student_department_id;
ALTER TABLE teacher_student DROP COLUMN IF EXISTS department_id;
@@ -0,0 +1,4 @@
-- Add department_id to teacher_student (nullable first, backfill, then not-null in future)
ALTER TABLE teacher_student ADD COLUMN department_id VARCHAR;
CREATE INDEX idx_teacher_student_department_id ON teacher_student (department_id);