下面的代码可以工作,但运行速度非常慢,如果我尝试使用太多PostalCode对象,就会超时。Address模型有大约100万个对象,查询每个循环都要花很长时间。显然,我这样做是错误的方式,所以任何帮助将不胜感激!这是我第一次处理大量数据。我看了看并尝试了交易(它确实工作,但仍然很慢),但我不确定这将如何帮助在这种情况下。如果它需要时间来运行,这是确定的,没有人会使用它,当我这样做定期更新,但它不能下降8小时或类似的东西,而这个过程运行。我知道我可以用celery 来卸下这些东西,但我还没有在我的学习中走得那么远,真的需要先了解这些基本原理。
型号:
class Address(models.Model):
name = models.CharField(max_length=200, blank=True, null=True)
address = models.CharField(max_length=300, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
province = models.CharField(max_length=100, blank=True, null=True)
postal_code = models.CharField(max_length=6, blank=True, null=True)
class Meta:
indexes = [
models.Index(fields=['postal_code',]),
]
def __str__(self):
return self.address
class PostalCode(models.Model):
postal_code = models.CharField(max_length=6, blank=True, null=True)
address = models.ForeignKey('Address', on_delete=models.DO_NOTHING, blank=True, null=True)
class Meta:
indexes = [
models.Index(fields=['postal_code',]),
]
def __str__(self):
return self.postal_code
字符串
查看:
def update_postal_code_addresses(request):
postal_codes = PostalCode.objects.all()
addresses = Address.objects.all()
objs = []
for pc in postal_codes.iterator():
try:
obj = addresses.get(postal_code=pc.postal_code) # this table has about 1M rows
pc.address = obj
objs.append(pc)
except Address.DoesNotExist:
pass
PostalCode.objects.bulk_update(objs, ['address'], batch_size=100)
return redirect('home')
型
3条答案
按热度按时间ffscu2ro1#
在这里获取
Address
对象是瓶颈。您可以批量获取Adress
对象并使用字典,如:字符串
注意,如果有两个
Address
具有 * 相同的 *postal_code
,那么我们将使用恰好是addresses
查询集中最新的一个。pxq42qpu2#
所有对Address表的读调用都是导致查询变慢的原因。有很多方法可以根据您的资源来帮助您的查询,但第一步是通过迭代到Address表而不是逐个收集它们,并通过将PostalCode存储在内存中(假设它是一个足够小的表,您可以这样做)来减少读取量。
我认为PostalCode比Address小得多,所以存储PostalCode更有意义,而且它允许我们在Address上进行子查询以检索较少的项目,而且由于您在postal_code字段上有Address索引,所以查询不应该太昂贵。
在你的模型中,PostalCode的postal_code字段不是唯一的,所以我们将按postal_code对PostalCode表进行分组,并假设几个PostalCode可能匹配同一个postal_code:
字符串
这将大大提高你的表现。
6ojccjat3#
一般建议。queryset越大,batch_size参数应该越小。从0到max1000是最佳的。