python - 过滤多个集合中的成员资格时如何避免 distinct()?
问题描述
我正在努力处理 django 中一个相当慢的查询,该查询需要显示按多个组的成员身份过滤的用户。结果列表只需要包含唯一用户,这对于小数字来说很好,但是在返回处理大型查询集时就变成了一个很大的问题。不幸的是,在这个阶段修改数据库结构并不可行,因为这是一个拥有大量活跃用户群的实时产品。
当前设置外观的基本示例:
class Group( models.Model ):
name = models.CharField(max_length=50)
class User( models.Model ):
name= models.CharField( max_length=100)
groups = models.ManyToManyField( Group, related_name='members' )
class UserDisplayModule( models.Model ):
display_groups = models.ManyToManyField( Group, related_name='display_modules' )
视图通常会加载一个模块,然后通过分配的组列出与该模块关联的所有用户,例如:
class UserModuleMembers( ModelViewSet ):
def get_queryset(self):
user_module = self.get_module()
return User.objects.filter(groups__in=module.display_groups.all()).distinct()[offset:offset+limit]
就列而言,实际模型要大得多,但关系确实如上。一个用户可能是多个组的成员,并且可以将多个组分配给一个模块,因此distinct()
此处需要一个子句,因为如果单个用户在附加到模块的多个组中具有特征,则可能会被多次选择。然后对生成的查询集进行分页。
以上对于小型应用程序来说效果很好,但我们正在快速增长,现在正在处理一个视图可能包含 100,000 多个用户的情况。即使有分页,这个查询也需要几秒钟才能返回。如果没有 distinct 子句,它会快很多,但是由于多组的事情,我们会得到重复的记录。
底层数据库是 postgres,我试图.distinct( 'name', 'id' )
限制考虑为“唯一性”的列,但这没有明显的区别。
如果有人可以建议一种替代方法,我真的很想听听!
解决方案
我更关心groups__in=module.display_groups.all()
小组部分。虽然子查询可以像简单的 JOIN 一样快,但通常很多数据库都在处理子查询。
可能有帮助的是在一个条件下用JOIN
s 来写这个。这也将使查询更简单,这通常意味着数据库可以更好地优化查询。
我们可以过滤:
User.objects.filter(groups__display_modules=module).distinct()
推荐阅读
- sql - Sequelize嵌套的渴望加载找到所有嵌套关联不匹配的地方
- sql - CASE 语句未获取 NULL 值
- javascript - 如何在 iFrame 上显示图像?
- r - 在 R 中使用“ptw”包
- typescript - 请将此代码转换为 TypeScript
- amazon-web-services - 安全组与角色的使用
- sockets - 自定义 UDP 协议的 sendto() 失败,使用 Seagull 协议流量生成器
- php - .zip 文件上传工具 aravel Laravel 5.6 Illuminate\Http\Exceptions\PostTooLargeException
- reactjs - 错误:在 React Native 安装期间被拒绝
- apache-spark - 从 ps 和 web-ui 隐藏 Spark 环境变量值