我应该在数据库中还是在Python中进行更新?

时间:2017-07-27 11:29:10

标签: python django

关于SO的原始问题是关于如何有效地链接大量记录。你们中的一些人真的帮了忙!这是我发现的。 您的情况可能会有所不同!

"最好在数据库中进行繁重的工作。"

我听说过,看过很多次。 WOW 是错的!这篇小小的文章记录了我产品开发中的一个重大突破。

您的应用会跟踪汽车的所有权,并将数据与它们相关联。以下是一些模型:

{
  "id": "123",
  "name": "John",
  "address.city": "Chennai",
  "address.town": "Guindy"
}

那么如何链接这些记录?我们关心日期和葡萄酒,对吧?例如,如果汽车是:

  • 6月1日出售
  • 维护工作于5月12日进行。
  • 维护工作于7月15日进行。

然后这些# There are ~2M OwnershipRecord models class OwnershipRecord(models.Model): vin = models.CharField(...) saledate = models.DateField(...) active = models.BooleanField(...) # There are ~1M MaintenanceRecord models class MaintenanceRecord(models.Model): vin = models.CharField(...) ownership_record = models.ForeignKey(OwnershipRecord, ...) mileage = models.DecimalField(...) date_in_shop = models.DateField(...) 链接到两个单独的MaintenanceRecord。您可以看到这将是一项密集型任务。我尝试过几种不同的链接方法。

  1. 将每个新的维护记录卸载到Celery。使用query查找正确的OwnershipRecord并创建ForeignKey关系。

    OwnershipRecord
  2. 使用新的Django 1.11工具match = OwnershipRecord.objects.filter(vin=mx_vin, saledate__lt=date_in_shop).order_by('-saledate').latest('saledate') Subquery对所有记录(或某些批处理子集)执行查询。卸载到芹菜。

    OuterRef
  3. 在内存中进行操作,按需批量或小批量进行操作。把它卸到Celery。

    possible_matches = OwnershipRecord.objects.filter(vin=OuterRef('vin'), saledate__lt=OuterRef('date_in_shop'))
    
    MaintenanceRecord.objects.filter(<subset_criteria>).update(ownership_record = Subquery(possible_matches)[:1])
    

1 个答案:

答案 0 :(得分:-1)

以下是结果

  1. 最慢。每个成功链接以秒为单位测量。
  2. 比#1快两倍。
  3. 与#1一样快100倍。
  4. 显然,在数据库中进行繁重的工作并不总是最好的。