Too many query of schedules when access the courseware

Hi everyone,

I’m currently working on improving the initial loading time for accessing courseware in our LMS at the path lms-domain/courses/{course_id}[/+]+{var}[/]+)/courseware/. On the first access, it takes about 2 to 5 seconds for the server to respond, during which the browser is just loading without displaying any content.

To diagnose the issue, I used Sentry to trace the processes happening in the background. I found that there are too many actions checking schedules in the schedules_schedule table in MySQL.

Here are my questions:

  1. Why are these schedule checks being performed repeatedly?
  2. Is there a way to disable these actions? I do not use the schedules feature or send emails to students.

Note: this is using maple version

1 Like

It’s possible that we’re either doing a check somewhere deep in a loop somewhere, or else we’re missing a select_related and it’s re-fetching when someone’s looking at the schedule attribute off of an enrollment object.

Does Sentry give you a line trace of where that’s coming from exactly? It should hopefully be relatively straightforward to either cache with a request cache or add the select_related if so.

@dave it’s coming from lms.djangoapps.courseware.views.index:CoursewareIndex.get

The following the query

SELECT `schedules_schedule`.`id`, `schedules_schedule`.`created`, `schedules_schedule`.`modified`, `schedules_schedule`.`enrollment_id`, `schedules_schedule`.`active`, `schedules_schedule`.`start_date`, `schedules_schedule`.`upgrade_deadline` FROM `schedules_schedule` INNER JOIN `student_courseenrollment` ON (`schedules_schedule`.`enrollment_id` = `student_courseenrollment`.`id`) WHERE (`student_courseenrollment`.`course_id` = %s AND `student_courseenrollment`.`user_id` = %s) LIMIT 21

Okay, dug a little bit deeper, and it looks like this is the detailed stack trace:

/openedx/edx-platform/lms/djangoapps/courseware/ in get_block_for_descriptor(455)

/openedx/edx-platform/xmodule/ in bind_for_student(617)
  wrapped_field_data = wrapper(wrapped_field_data)

/openedx/venv/lib/python3.11/site-packages/edx_when/ in __init__(51)
  self._load_dates(course_id, user, use_cached=use_cached)

/openedx/venv/lib/python3.11/site-packages/edx_when/ in _load_dates(59)
  for (location, field), date in api.get_dates_for_course(course_id, user, use_cached=use_cached).items():

/openedx/venv/lib/python3.11/site-packages/edx_when/ in get_dates_for_course(196)
  schedule = get_schedule_for_user(user_id, course_id)

/openedx/venv/lib/python3.11/site-packages/edx_when/ in get_schedule_for_user(19)
  return Schedule.objects.get(enrollment__user__id=user_id, enrollment__course__id=course_key)

Which probably means that we need to patch up this function to use the request cache:

There are other problems with that code and the way the model dependencies are working here, but that’s a problem for another day.

I am very coincidentally looking into Unit rendering time and XBlock runtime overhead related to a different proposal this week. I’ll see if this straightforward to patch.

I’ve started a PR with a fix for this here:

@icarrr: Do you know if this particular trace you’re seeing is happening for a Unit with many components in it?

Please note that I’m taking some time off starting in the middle of next week, so this likely won’t be merged until the end of the month or so (unless someone wants to take over the PR and test/merge before then).

@dave yes, this also happens in units with many components. It also occurs when navigating to other subsections.