Django queryset上的这个循环是最优的吗?
如果没有,我可以做些什么来改进它?目前,仅用我们的开发数据进行评估需要13秒。原始SQL的想法Django queryset上的这个循环是最优的吗?,django,postgresql,django-queryset,Django,Postgresql,Django Queryset,如果没有,我可以做些什么来改进它?目前,仅用我们的开发数据进行评估需要13秒。原始SQL的想法 suppliers = models.Supplier.objects.all().order_by('company') for supplier in suppliers : sup = {} sup['company'] = supplier.company sup['supplies'] = get_supplies(1, sup
suppliers = models.Supplier.objects.all().order_by('company')
for supplier in suppliers :
sup = {}
sup['company'] = supplier.company
sup['supplies'] = get_supplies(1, supplier.uuid)
sup['category'] = 'Supplier'
if isocode == None :
addresses = models.Address.objects.filter(company = supplier.company).iterator()
else :
addresses = models.Address.objects.filter(company = supplier.company, country_iso = isocode).iterator()
sup['contacts'] = list(models.Contact.objects.filter(address__in=addresses))
company_list.append(sup)
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------ 可以重新编写为:
sup['contacts'] = models.Contact.objects.filter(address__in=addresses)
Sups最终将成为Queryset对象,在使用它时将对其进行计算。如果确实需要列表,请执行以下操作,这将立即计算QuerySet并为您提供一个Python列表对象:
sup['contacts'] = list(models.Contact.objects.filter(address__in=addresses))
https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-对查询集进行评估首先,添加
。在初始供应商查询中选择相关(“公司”)
。现在,每次访问循环中的supplier.company
时,您都会发出一个额外的查询
查询膨胀的其余部分来自分别选择
Address
和Contact
。每次通过循环都必须发出另外两个查询。如果您使用的是Django 1.4+,您可以尝试使用来删除这些内容。如果您正在运行一个较小的版本,您可以尝试提供类似的功能。这可能需要重新思考一下您的方法,以找到一种方法来同时选择所有内容。这有点帮助,但仍然需要很长时间。。我会把剩下的贴出来,看看是否有比我想象的更多的问题,看看你的实际模型会有帮助。查询优化最重要的是正确使用关系,如果没有模型,我们无法知道这一点。不幸的是,我不允许这样做为什么不?“我不是要数据,只是要模型布局,没有什么秘密。”克里斯普拉特必须先说服老板
class Address(models.Model):
uuid = UUIDField(primary_key=True)
company = models.ForeignKey(Company, db_column='company_uuid',null=True,blank=True,verbose_name=_('Address'))
group_name = models.CharField(null=True, blank=False,max_length=255,verbose_name=_('Corporate Group'))
line1 = models.CharField(null=True, blank=False,max_length=255,verbose_name=_('Address Line 1'))
line2 = models.CharField(null=True, blank=True,max_length=255,verbose_name=_('Address Line 2'))
line3 = models.CharField(null=True, blank=True,max_length=255,verbose_name=_('Address Line 3'))
town = models.CharField(null=True, blank=True,max_length=255)
county = models.CharField(null=True, blank=True,max_length=255)
postcode = models.CharField(null=True, blank=True,max_length=255)
country_iso = models.CharField(null=True, blank=True,max_length=255)
telephone = models.CharField(null=True, blank=True,max_length=255)
fax = models.CharField(null=True, blank=True,max_length=255)
email = models.CharField(null=True, blank=True,max_length=255)
website = models.CharField(null=True, blank=True,max_length=255)
description = models.CharField(null=True, blank=True,max_length=255)
date_created = models.DateTimeField(null=True, blank=True, auto_now_add=True)
date_modified = models.DateTimeField(null=True, blank=True, auto_now=True)
user = UserField(null=True, blank=True)
jms_code = models.CharField(null=True, blank=True,max_length=255)
allow_download = models.NullBooleanField(serialize=False)
notes = models.CharField(null=True, blank=True,max_length=255)
is_modified = ModifiedField(serialize=False)
def __unicode__(self):
if self.description in [ '', None ] :
if self.line1 not in [ '', None ] :
return self.line1
return self.uuid
return self.description
def asList (self) :
return [ b for b in self.line1, self.line2, self.line3, self.town, self.county if b not in ('', None) ]
class Meta:
db_table = 'address'
verbose_name_plural = ('Addresses')
sup['contacts'] = Contact.objects.filter(address__in=addresses)
sup['contacts'] = models.Contact.objects.filter(address__in=addresses)
sup['contacts'] = list(models.Contact.objects.filter(address__in=addresses))