Django - join / no join存在过滤器之间的性能差异

时间:2017-08-10 05:52:51

标签: mysql django postgresql optimization django-models

目前我有一个类似Tinder的应用程序,可以使用以下模型

class User(models.Model):
    id      = models.BigAutoField(primary_key=True)
    name    = models.CharField(max_length=50)
    age     = models.PositiveIntegerField()
    pic_url = Models.CharField(max_length=100)

class Rating(models.Model):
    id       = models.BigAutoField(primary_key=True)
    by_user  = models.ForeignKey(User,
                                 on_delete=models.PROTECT,
                                 related_name='written_ratings')
    for_user = models.ForeignKey(User,
                                 on_delete=models.PROTECT,
                                 related_name='received_ratings')
    like     = models.BooleanField()

为了让新的User对象左右滑动,我们需要为尚未评级的用户查询数据库(PostgresSQL)。我目前通过执行以下查询来执行此操作

users_that_i_havent_rated_yet = models.User.objects.all().exclude(
                                    id=current_user_id
                                ).filter(
                                    age__gte=some_minimum_age,
                                    age__lte=some_maximum_age,
                                ).exclude(
                                    received_ratings__by_user_id=current_user_id
                                )

现在,我打算将User对象分隔为Profile对象,以便维护用户对其个人资料的更改的“历史记录”作为其他无关信息的容器(也因为我的教授要求我们为我们的项目执行此操作)

# as the user changes their profile pictures, we will just create 
# a new `Profile` object and set the `current_profile` pointing to it
class User(models.Model):
    id              = models.BigAutoField(primary_key=True)
    name            = models.CharField(max_length=50)
    age             = models.PositiveIntegerField()
    current_profile = models.OneToOneField(Profile,
                                           on_delete=models.PROTECT)

class Profile(models.Model):
    id      = models.BigAutoField(primary_key=True)
    pic_url = models.CharField(max_length=100)
    by_user = models.ForeignKey(User,
                                on_delete=models.PROTECT,
                                related_name='created_profiles')

class Rating(models.Model):
    id          = models.BigAutoField(primary_key=True)
    by_user     = models.ForeignKey(User,
                                    on_delete=models.PROTECT,
                                    related_name='written_ratings')
    for_profile = models.ForeignKey(Profile,
                                    on_delete=models.PROTECT,
                                    related_name='received_ratings')
    like        = models.BooleanField()

现在,由于信息被分成2个表,因此查询变为

users_that_i_havent_rated_yet = models.User.objects.all().exclude(
                                    id=current_user_id
                                ).filter(
                                    age__gte=some_minimum_age,
                                    age__lte=some_maximum_age,
                                ).exclude(
                                    current_profile__received_ratings__by_user_id=current_user_id
                                )

此附加连接是否会显着影响查询的性能?有更好的方法吗?

0 个答案:

没有答案