Django F() 对象的性能问题

发布于 2024-08-28 12:46:40 字数 2269 浏览 5 评论 0原文

有没有其他人注意到使用 Django 的 F() 对象的性能问题?我正在运行 Windows XP SP3 并针对 Django trunk 进行开发。下面是我正在使用的模型和正在构建的查询的片段。当我有 F() 对象时,每次调用 QuerySet 方法(例如,filter、exclusive、order_by、distinct 等)大约需要 2 秒,但是当我注释掉 F() 子句时,调用是 sub-第二。我让一位同事在他的 Ubuntu 机器上测试了它,他没有遇到与 F() 子句相同的性能问题。

还有其他人看到这种行为吗?

class Move (models.Model):
    state_meaning = models.CharField(
        max_length=16,
        db_index=True,
        blank=True,
        default=''
    )
    drop = models.ForeignKey(
        Org,
        db_index=True,
        null=False,
        default=1,
        related_name='as_move_drop'
    )

class Split(models.Model):
    state_meaning = models.CharField(
        max_length=16,
        db_index=True,
        blank=True,
        default=''
    )
    move = models.ForeignKey(
        Move,
        related_name='splits'
    )
    pickup = models.ForeignKey(
        Org,
        db_index=True,
        null=False,
        default=1,
        related_name='as_split_pickup'
    )
    pickup_date = models.DateField(
        null=True,
        default=None
    )
    drop = models.ForeignKey(
        Org,
        db_index=True,
        null=False,
        default=1,
        related_name='as_split_drop'
    )
    drop_date = models.DateField(
        null=True,
        default=None,
        db_index=True
    )

def get_splits(begin_date, end_date):
    qs = Split.objects \
        .filter(state_meaning__in=['INPROGRESS','FULFILLED'],
                drop=F('move__drop'), # <<< the line in question
                pickup_date__lte=end_date)

    elapsed = timer.clock() - start
    print 'qs1 took %.3f' % elapsed
    start = timer.clock()

    qs = qs.filter(Q(drop_date__gte=begin_date) |
                   Q(drop_date__isnull=True))

    elapsed = timer.clock() - start
    print 'qs2 took %.3f' % elapsed
    start = timer.clock()

    qs = qs.exclude(move__state_meaning='UNFULFILLED')

    elapsed = timer.clock() - start
    print 'qs3 took %.3f' % elapsed
    start = timer.clock()

    qs = qs.order_by('pickup_date', 'drop_date')

    elapsed = timer.clock() - start
    print 'qs7 took %.3f' % elapsed
    start = timer.clock()

    qs = qs.distinct()

    elapsed = timer.clock() - start
    print 'qs8 took %.3f' % elapsed

Has anyone else noticed performance issues using Django's F() object? I am running Windows XP SP3 and developing against the Django trunk. A snippet of the models I'm using and the query I'm building are below. When I have the F() object in place, each call to a QuerySet method (e.g. filter, exclude, order_by, distinct, etc.) takes approximately 2 seconds, but when I comment out the F() clause the calls are sub-second. I had a co-worker test it on his Ubuntu machine, and he is not experiencing the same performance issues I am with the F() clause.

Anyone else seeing this behavior?

class Move (models.Model):
    state_meaning = models.CharField(
        max_length=16,
        db_index=True,
        blank=True,
        default=''
    )
    drop = models.ForeignKey(
        Org,
        db_index=True,
        null=False,
        default=1,
        related_name='as_move_drop'
    )

class Split(models.Model):
    state_meaning = models.CharField(
        max_length=16,
        db_index=True,
        blank=True,
        default=''
    )
    move = models.ForeignKey(
        Move,
        related_name='splits'
    )
    pickup = models.ForeignKey(
        Org,
        db_index=True,
        null=False,
        default=1,
        related_name='as_split_pickup'
    )
    pickup_date = models.DateField(
        null=True,
        default=None
    )
    drop = models.ForeignKey(
        Org,
        db_index=True,
        null=False,
        default=1,
        related_name='as_split_drop'
    )
    drop_date = models.DateField(
        null=True,
        default=None,
        db_index=True
    )

def get_splits(begin_date, end_date):
    qs = Split.objects \
        .filter(state_meaning__in=['INPROGRESS','FULFILLED'],
                drop=F('move__drop'), # <<< the line in question
                pickup_date__lte=end_date)

    elapsed = timer.clock() - start
    print 'qs1 took %.3f' % elapsed
    start = timer.clock()

    qs = qs.filter(Q(drop_date__gte=begin_date) |
                   Q(drop_date__isnull=True))

    elapsed = timer.clock() - start
    print 'qs2 took %.3f' % elapsed
    start = timer.clock()

    qs = qs.exclude(move__state_meaning='UNFULFILLED')

    elapsed = timer.clock() - start
    print 'qs3 took %.3f' % elapsed
    start = timer.clock()

    qs = qs.order_by('pickup_date', 'drop_date')

    elapsed = timer.clock() - start
    print 'qs7 took %.3f' % elapsed
    start = timer.clock()

    qs = qs.distinct()

    elapsed = timer.clock() - start
    print 'qs8 took %.3f' % elapsed

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文