diff --git a/common/djangoapps/django_comment_common/models.py b/common/djangoapps/django_comment_common/models.py
index 0d27aa9a07efe8c49386dd2128733adf19683f15..a0b48c4c2feef5ee74d1b114f3a80f0a08e0de7e 100644
--- a/common/djangoapps/django_comment_common/models.py
+++ b/common/djangoapps/django_comment_common/models.py
@@ -145,13 +145,25 @@ def all_permissions_for_user_in_course(user, course_id):  # pylint: disable=inva
     if course is None:
         raise ItemNotFoundError(course_id)
 
-    all_roles = {role.name for role in Role.objects.filter(users=user, course_id=course_id)}
+    all_roles = {role for role in Role.objects.filter(users=user, course_id=course_id)}
+    role_names = {role.name for role in all_roles}
+
+    # TODO: EDUCATOR-3374
+    # The `roles__users__roles__in=all_roles` part of this filter is a hack to get the new
+    # Aurora MySql query planner to properly use the unique index on the roles/users join table.
+    # Without this hack, the planner uses a unique index on (role_id, user_id) to do lookup
+    # by user_id only, which is a completely inefficient way to use that index.
+    permission_queryset = Permission.objects.filter(
+        roles__users=user,
+        roles__course_id=course_id,
+        roles__users__roles__in=all_roles
+    ).distinct()
 
     permissions = {
         permission.name
         for permission
-        in Permission.objects.filter(roles__users=user, roles__course_id=course_id)
-        if not permission_blacked_out(course, all_roles, permission.name)
+        in permission_queryset
+        if not permission_blacked_out(course, role_names, permission.name)
     }
     return permissions
 
diff --git a/lms/djangoapps/courseware/tests/test_discussion_xblock.py b/lms/djangoapps/courseware/tests/test_discussion_xblock.py
index 10b8bbacd5a8244052fead02e6a2090df252d4a3..d57267d4cc5878e98b15ee34d0dc9a5417d623c5 100644
--- a/lms/djangoapps/courseware/tests/test_discussion_xblock.py
+++ b/lms/djangoapps/courseware/tests/test_discussion_xblock.py
@@ -402,11 +402,13 @@ class TestXBlockQueryLoad(SharedModuleStoreTestCase):
                 discussion_target='Target Discussion',
             ))
 
-        # 3 queries are required to do first discussion xblock render:
+        # 2 queries are required to do first discussion xblock render:
         # * django_comment_client_role
-        # * django_comment_client_permission
         # * lms_xblock_xblockasidesconfig
-        num_queries = 3
+        # If the query for roles returned a non-empty result set, there would be
+        # an additional query against django_comment_client_permission, but there
+        # are no roles associated with this test.
+        num_queries = 2
         for discussion in discussions:
             discussion_xblock = get_module_for_descriptor_internal(
                 user=user,