• 
      

    Speed up user search indexing by fixing query cache usage for profiles.

    Review Request #15013 — Created April 15, 2026 and submitted

    Information

    Review Board
    release-7.1.x

    Reviewers

    User.get_profile() has checks in place to make use of any profile
    fetched along with the user via select_related() or
    prefetch_related().

    In the case where the cached profile result is a None, we were falling
    back on default behavior based on the create_if_missing flag. This is
    fine if the flag is True (we want to create) but if the flag is
    False a redundant fetch would occur, which would likely still return a
    None result.

    This code now respects a None entry in the cache in this case, which
    will raise Profile.DoesNotExist as it would have before, but without
    the redundant database query.

    This will significantly speed up search indexing for users, which was
    performing 4 queries per user.

    Unit tests pass.

    Built new unit tests (for an upcoming change) that found this issue and
    verified the fix.

    Summary ID
    Speed up user search indexing by fixing query cache usage for profiles.
    `User.get_profile()` has checks in place to make use of any profile fetched along with the user via `select_related()` or `prefetch_related()`. In the case where the cached profile result is a `None`, we were falling back on default behavior based on the `create_if_missing` flag. This is fine if the flag is `True` (we want to create) but if the flag is `False` a redundant fetch would occur, which would likely still return a `None` result. This code now respects a `None` entry in the cache in this case, which will raise `Profile.DoesNotExist` as it would have before, but without the redundant database query. This will significantly speed up search indexing for users, which was performing 4 queries per user.
    0d8312240a2242ecc0271ca0a0d8f2e432242e57
    Description From Last Updated

    This method now returns None if we've done select_related('profile') and the profile doesn't exist (where previously it would raise DoesNotExist. …

    david david

    This should be updated to say that we explicitly do not fetch if the cache variable was already set to …

    david david

    local variable 'profile' is assigned to but never used Column: 13 Error code: F841

    reviewbot reviewbot

    Can we add num_statements to this?

    david david

    Can we add num_statements to this?

    david david

    Can we add num_statements to this?

    david david
    maubin
    1. Ship It!
    2. 
        
    david
    1. 
        
    2. reviewboard/accounts/models.py (Diff revision 1)
       
       
       
       
       
       
       
      Show all issues

      This method now returns None if we've done select_related('profile') and the profile doesn't exist (where previously it would raise DoesNotExist. It would be nice to clarify that here. as well as add a "Version Changed" block.

      1. I'll just restore this to raise a DoesNotExist again. The main thing is to avoid an unnecessary query.

    3. reviewboard/accounts/models.py (Diff revision 1)
       
       
       
       
       
      Show all issues

      This should be updated to say that we explicitly do not fetch if the cache variable was already set to None

    4. 
        
    chipx86
    Review request changed
    Change Summary:
    • Restored the Profile.DoesNotExist error.
    • Clarified the conditions in a comment.
    Description:
       

    User.get_profile() has checks in place to make use of any profile

        fetched along with the user via select_related() or
        prefetch_related().

       
       

    In the case where the cached profile result is a None, we were falling

        back on default behavior based on the create_if_missing flag. This is
        fine if the flag is True (we want to create) but if the flag is
        False a redundant fetch would occur, which would likely still return a
        None result.

       
    ~  

    This code now respects a None entry in the cache in this case,

    ~   returning the None directly without the extra fetch.

      ~

    This code now respects a None entry in the cache in this case, which

      ~ will raise Profile.DoesNotExist as it would have before, but without
      + the redundant database query.

       
       

    This will significantly speed up search indexing for users, which was

        performing 4 queries per user.

    Commits:
    Summary ID
    Speed up user search indexing by fixing query cache usage for profiles.
    `User.get_profile()` has checks in place to make use of any profile fetched along with the user via `select_related()` or `prefetch_related()`. In the case where the cached profile result is a `None`, we were falling back on default behavior based on the `create_if_missing` flag. This is fine if the flag is `True` (we want to create) but if the flag is `False` a redundant fetch would occur, which would likely still return a `None` result. This code now respects a `None` entry in the cache in this case, returning the `None` directly without the extra fetch. This will significantly speed up search indexing for users, which was performing 4 queries per user.
    a811778bca289d5549c5ab3e0db679d6212b4ef7
    Speed up user search indexing by fixing query cache usage for profiles.
    `User.get_profile()` has checks in place to make use of any profile fetched along with the user via `select_related()` or `prefetch_related()`. In the case where the cached profile result is a `None`, we were falling back on default behavior based on the `create_if_missing` flag. This is fine if the flag is `True` (we want to create) but if the flag is `False` a redundant fetch would occur, which would likely still return a `None` result. This code now respects a `None` entry in the cache in this case, which will raise `Profile.DoesNotExist` as it would have before, but without the redundant database query. This will significantly speed up search indexing for users, which was performing 4 queries per user.
    42bd585f0143ac18e69067bf74afa9d16f988729

    Checks run (1 failed, 1 succeeded)

    flake8 failed.
    JSHint passed.

    flake8

    chipx86
    david
    1. 
        
    2. reviewboard/accounts/tests/test_user.py (Diff revision 3)
       
       
      Show all issues

      Can we add num_statements to this?

      1. num_statements is legacy and no longer used by django-assert-queries in any capacity. It was a holdover from older versions of the support in Djblets.

    3. reviewboard/accounts/tests/test_user.py (Diff revision 3)
       
       
      Show all issues

      Can we add num_statements to this?

    4. reviewboard/accounts/tests/test_user.py (Diff revision 3)
       
       
      Show all issues

      Can we add num_statements to this?

    5. 
        
    chipx86
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-8.x (cb548c3)