我在Django项目中使用了方便的Django sessions library。这允许我通过ORM查询处理Session对象。
我可以为每个Session对象访问的属性是:
Column | Type | Modifiers
---------------+--------------------------+-----------
session_key | character varying(40) | not null
session_data | text | not null
expire_date | timestamp with time zone | not null
user_id | integer |
user_agent | character varying(200) | not null
last_activity | timestamp with time zone | not null
ip | inet | not null
user_id
来自Django User
模型。
使用会话库,我需要找到我的应用中当前在会话表中没有条目的用户数(以及相应的IDs
)。
我通过以下方式尝试了它:
logged_in_users = set(Session.objects.values_list('user_id',flat=True))
logged_in_users = [user_pk for user_pk in logged_in_users if user_pk is not None]
logged_out_users = set(User.objects.exclude(id__in=logged_in_users).values_list('id',flat=True))
num_logged_out = len(logged_out_users) #passed to template to display
我的会话表包含 1.7M 行,而用户表包含 408K 行。上面的代码占用了异常大量的处理时间(即几分钟),最终在生产中产生了500错误(在开发中的有限数据集上正常工作)。
在解决问题之前,我觉得我也应该优化查询以降低成本。
您觉得我的代码需要哪些明显的优化?我知道我可以通过从logged_out_users
中减去logged_in_users
的数量来找到total_users
的数量。但是如何获取所有ID?
答案 0 :(得分:1)
[更新] :在评论中进行了一些讨论之后,问题是检索(并计算)已注销的id
的{{1}}(即用户)在User
表中根本没有条目。
所以:
Session
这个怎么样:
# Get a (flat) list of user ids where the user entry in not null
logged_in_users = Session.objects.filter(user__isnull=False).values_list('user__id', flat=True).distinct()
# Get a (flat) list of user ids excluding the previous logged ones (thus, this list will contain the logged out users)
logged_out_users = User.objects.exclude(id__in=logged_in_users).values_list('id', flat=True).distinct()
# Count the logged out users
logged_out_users_count = logged_out_users.count()