是不是“更好”了? 有更新字段或 COUNT 查询吗?
在我正在开发的 Django 应用程序中,我遇到了这样的情况:
class Parent(models.Model):
name = models.CharField(...)
def num_children(self):
return Children.objects.filter(parent=self).count()
def avg_child_rating(self):
return Child.objects.filter(parent=self).aggregate(Avg('rating'))
class Child(models.Model):
name = models.CharField(...)
parent = models.ForeignKey(Parent)
rating = models.IntegerField(default=0)
我计划经常访问 avg_child_ rating 。 如果我执行以下操作,是否会进行优化:
class Parent(models.Model):
...
num_children = models.IntegerField(default=0)
avg_child_rating = models.FloatField(default=0.0)
def update_parent_child_stats(sender, instance, **kwargs):
num_children = Child.objects.filter(parent=instance.parent)
if instance.parent.num_children != num_children:
instance.parent.num_children = num_children
instance.parent.avg_child_rating = Child.objects.filter(instance.parent=self).aggregate(Avg('rating'))
post_save.connect(update_parent_child_stats, sender=Child)
post_delete.connect(update_parent_child_stats, sender=Child)
现在的区别是,每次创建/评级/删除子项时,父对象都会更新。 我知道创建/评级会经常进行。
什么更贵?
In a Django App I'm working on I've got this going on:
class Parent(models.Model):
name = models.CharField(...)
def num_children(self):
return Children.objects.filter(parent=self).count()
def avg_child_rating(self):
return Child.objects.filter(parent=self).aggregate(Avg('rating'))
class Child(models.Model):
name = models.CharField(...)
parent = models.ForeignKey(Parent)
rating = models.IntegerField(default=0)
I plan on accessing avg_child_rating often. Would it be optimizing if I did the following:
class Parent(models.Model):
...
num_children = models.IntegerField(default=0)
avg_child_rating = models.FloatField(default=0.0)
def update_parent_child_stats(sender, instance, **kwargs):
num_children = Child.objects.filter(parent=instance.parent)
if instance.parent.num_children != num_children:
instance.parent.num_children = num_children
instance.parent.avg_child_rating = Child.objects.filter(instance.parent=self).aggregate(Avg('rating'))
post_save.connect(update_parent_child_stats, sender=Child)
post_delete.connect(update_parent_child_stats, sender=Child)
The difference now is that every time a child is created/rated/deleted, the Parent object is updated. I know that the created/rating will be done often.
What's more expensive?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
取决于问题的严重程度。
如果您预计会有大量写入流量,这可能是一个问题。 扩展写入比扩展读取(复制、缓存等)要困难得多。也就是说,您可能可以走很长一段路,而不会因为这个额外的查询而导致任何问题。
根据您的统计数据的最新程度,您可以让其他进程(非网络会话)完成并每晚更新这些统计数据。
Depends on the scale of the problem.
If you anticipate a lot of write traffic, this might be an issue. It's much harder to scale writes than reads (replicate, caching etc.) That said, you can probably going a long way without this extra query causing you any problems.
Depending on how up-to-date your stats must be you could have some other process (non-web session) come through and update these stats nightly.