mirror of https://github.com/zulip/zulip.git
users: Refactor and optimize max_message_id_for_user by removing a join.
This algorithm existed in multiple places, with different queries. Since we only access properties in the UserMessage table, we standardize on the much simpler and faster Index Only Scan, rather than a merge join.
This commit is contained in:
parent
0c88cfca63
commit
631868a05b
|
@ -54,17 +54,20 @@ from zerver.lib.topic import TOPIC_NAME
|
|||
from zerver.lib.user_groups import user_groups_in_realm_serialized
|
||||
from zerver.lib.user_status import get_user_status_dict
|
||||
from zerver.lib.user_topics import get_topic_mutes, get_user_topics
|
||||
from zerver.lib.users import get_cross_realm_dicts, get_raw_user_data, is_administrator_role
|
||||
from zerver.lib.users import (
|
||||
get_cross_realm_dicts,
|
||||
get_raw_user_data,
|
||||
is_administrator_role,
|
||||
max_message_id_for_user,
|
||||
)
|
||||
from zerver.models import (
|
||||
MAX_TOPIC_NAME_LENGTH,
|
||||
Client,
|
||||
CustomProfileField,
|
||||
Draft,
|
||||
Message,
|
||||
Realm,
|
||||
RealmUserDefault,
|
||||
Stream,
|
||||
UserMessage,
|
||||
UserProfile,
|
||||
UserStatus,
|
||||
UserTopic,
|
||||
|
@ -182,17 +185,7 @@ def fetch_initial_state_data(
|
|||
# `max_message_id` is primarily used for generating `local_id`
|
||||
# values that are higher than this. We likely can eventually
|
||||
# remove this parameter from the API.
|
||||
user_messages = None
|
||||
if user_profile is not None:
|
||||
user_messages = (
|
||||
UserMessage.objects.filter(user_profile=user_profile)
|
||||
.order_by("-message_id")
|
||||
.values("message_id")[:1]
|
||||
)
|
||||
if user_messages:
|
||||
state["max_message_id"] = user_messages[0]["message_id"]
|
||||
else:
|
||||
state["max_message_id"] = -1
|
||||
state["max_message_id"] = max_message_id_for_user(user_profile)
|
||||
|
||||
if want("drafts"):
|
||||
if user_profile is None:
|
||||
|
@ -1232,13 +1225,7 @@ def apply_event(
|
|||
message_ids = [event["message_id"]]
|
||||
else:
|
||||
message_ids = event["message_ids"] # nocoverage
|
||||
max_message = (
|
||||
Message.objects.filter(usermessage__user_profile=user_profile).order_by("-id").first()
|
||||
)
|
||||
if max_message:
|
||||
state["max_message_id"] = max_message.id
|
||||
else:
|
||||
state["max_message_id"] = -1
|
||||
state["max_message_id"] = max_message_id_for_user(user_profile)
|
||||
|
||||
if "raw_unread_msgs" in state:
|
||||
for remove_id in message_ids:
|
||||
|
|
|
@ -26,6 +26,7 @@ from zerver.models import (
|
|||
CustomProfileFieldValue,
|
||||
Realm,
|
||||
Service,
|
||||
UserMessage,
|
||||
UserProfile,
|
||||
get_realm_user_dicts,
|
||||
get_user,
|
||||
|
@ -622,3 +623,18 @@ def get_users_with_access_to_real_email(user_profile: UserProfile) -> List[int]:
|
|||
user_profile.email_address_visibility,
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def max_message_id_for_user(user_profile: Optional[UserProfile]) -> int:
|
||||
if user_profile is None:
|
||||
return -1
|
||||
max_message = (
|
||||
UserMessage.objects.filter(user_profile=user_profile)
|
||||
.order_by("-message_id")
|
||||
.only("message_id")
|
||||
.first()
|
||||
)
|
||||
if max_message:
|
||||
return max_message.message_id
|
||||
else:
|
||||
return -1
|
||||
|
|
|
@ -67,6 +67,7 @@ from zerver.lib.users import (
|
|||
check_valid_interface_type,
|
||||
get_api_key,
|
||||
get_raw_user_data,
|
||||
max_message_id_for_user,
|
||||
validate_user_custom_profile_data,
|
||||
)
|
||||
from zerver.lib.utils import generate_api_key
|
||||
|
@ -88,7 +89,6 @@ from zerver.models import (
|
|||
DomainNotAllowedForRealmError,
|
||||
EmailContainsPlusError,
|
||||
InvalidFakeEmailDomainError,
|
||||
Message,
|
||||
Service,
|
||||
Stream,
|
||||
UserProfile,
|
||||
|
@ -743,11 +743,7 @@ def get_profile_backend(request: HttpRequest, user_profile: UserProfile) -> Http
|
|||
)
|
||||
result: Dict[str, Any] = raw_user_data[user_profile.id]
|
||||
|
||||
result["max_message_id"] = -1
|
||||
|
||||
messages = Message.objects.filter(usermessage__user_profile=user_profile).order_by("-id")[:1]
|
||||
if messages:
|
||||
result["max_message_id"] = messages[0].id
|
||||
result["max_message_id"] = max_message_id_for_user(user_profile)
|
||||
|
||||
return json_success(request, data=result)
|
||||
|
||||
|
|
Loading…
Reference in New Issue