"Лучше" иметь поле обновления или запрос COUNT? - PullRequest
0 голосов
/ 16 января 2009

В приложении 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)

Разница в том, что каждый раз, когда дочерний объект создается / оценивается / удаляется, родительский объект обновляется. Я знаю, что созданный / рейтинг будет сделан часто.

Что еще дорого ?

1 Ответ

3 голосов
/ 16 января 2009

Зависит от масштаба проблемы. Если вы ожидаете много трафика записи, это может быть проблемой. Гораздо сложнее масштабировать записи, чем чтения (репликация, кэширование и т. Д.). Тем не менее, вы, вероятно, сможете проделать долгий путь без дополнительных запросов, вызывающих у вас какие-либо проблемы.

В зависимости от того, насколько актуальной должна быть ваша статистика, у вас может быть какой-то другой процесс (без веб-сеанса), который обновляет эту статистику каждую ночь.

...