Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用大型子查询优化Django查询_Python_Django_Django Orm - Fatal编程技术网

Python 使用大型子查询优化Django查询

Python 使用大型子查询优化Django查询,python,django,django-orm,Python,Django,Django Orm,我有一个包含Profile和Relationship模型的数据库。我没有在模型中明确链接它们(因为它们是第三方id,并且可能还不存在于两个表中),但是源和目标字段通过id字段映射到一个或多个配置文件对象: from django.db import models class Profile(models.Model): id = models.BigIntegerField(primary_key=True) handle = models.CharField(max_lengt

我有一个包含
Profile
Relationship
模型的数据库。我没有在模型中明确链接它们(因为它们是第三方id,并且可能还不存在于两个表中),但是
目标
字段通过
id
字段映射到一个或多个
配置文件
对象:

from django.db import models
class Profile(models.Model):
    id = models.BigIntegerField(primary_key=True)
    handle = models.CharField(max_length=100)

class Relationship(models.Model):
    id = models.AutoField(primary_key=True)
    source = models.BigIntegerField(db_index=True)
    target = models.BigIntegerField(db_index=True)
我的查询需要从
Relationship.source
列中获取100个值的列表,这些值尚未作为
Profile.id
存在。然后,该列表将用于从第三方收集必要的数据。下面的查询可以工作,但随着表的增长(10m+),子查询变得非常大且速度很慢

关于如何优化这一点,有什么建议吗?后端是PostgreSQL,但如果可能的话,我想使用原生Django ORM

编辑:有一个额外的复杂性水平,将有助于缓慢的查询。并不是所有的ID都保证返回成功,这意味着它们继续“不存在”,并在无限循环中获取程序。因此,我添加了一个
过滤器
order\u by
,以输入上一批100中最高的
id
。这将导致一些问题,因此,对于最初错过它,我们深表歉意

from django.db.models import Subquery
user = Profile.objects.get(handle="philsheard")
qs_existing_profiles = Profiles.objects.all()
rels = TwitterRelationship.objects.filter(
    target=user.id,
).exclude(
    source__in=Subquery(qs_existing_profiles.values("id"))
).values_list(
    "source", flat=True
).order_by(
    "source"
).filter(
    source__gt=max_id_from_previous_batch  # An integer representing a previous `Relationship.source` id
)

提前感谢您的建议

对于未来的搜索者,以下是我如何在查询中绕过
\u,并能够加快搜索结果的速度

from django.db.models import Subquery
from django.db.models import Count  # New

user = Profile.objects.get(handle="philsheard")
subq = Profile.objects.filter(profile_id=OuterRef("source"))  # New queryset to use within Subquery
rels = Relationship.objects.order_by(
    "source"
).annotate(
    # Annotate each relationship record with a Count of the times that the "source" ID
    # appears in the `Profile` table. We can then filter on those that have a count of 0
    # (ie don't appear and therefore haven't yet been connected)
    prof_count=Count(Subquery(subq.values("id")))
).filter(
    target=user.id,
    prof_count=0
).filter(
    source__gt=max_id_from_previous_batch  # An integer representing a previous `Relationship.source` id
).values_list(
    "source", flat=True
)

我认为这会更快,因为一旦查询达到所需的100个项目(而不是每次与100多个ID的列表进行比较),它就会完成。

好吧,
查询中的
并不是最佳选择,尤其是对于1000多行。尝试将源作为foreignkey。或者使用任何(…)来获得更快的结果。谢谢@style。我不熟悉Django ORM上下文中的
ANY()
。你能提供一个简单的例子吗?我不知道如何在django ORM中实现。。或者是否可能,但您可以将其作为本机查询添加。另一种解决方案是在插入新关系时对其进行分析,并使用一个布尔字段
related\u to\u profile
——这样您就可以查询它了