第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用索引和更好的 SQL 在循環(huán)中優(yōu)化 QuerySet

使用索引和更好的 SQL 在循環(huán)中優(yōu)化 QuerySet

幕布斯7119047 2022-05-24 16:51:21
我有一個返回一些關于電子郵件列表增長的統(tǒng)計數(shù)據(jù)的視圖。涉及的模型有:模型.pyclass Contact(models.Model):    email_list = models.ForeignKey(EmailList, related_name='contacts')    customer = models.ForeignKey('Customer', related_name='contacts')    status = models.CharField(max_length=8)    create_date = models.DateTimeField(auto_now_add=True)class EmailList(models.Model):    customers = models.ManyToManyField('Customer',        related_name='lists',        through='Contact')class Customer(models.Model):    is_unsubscribed = models.BooleanField(default=False, db_index=True)    unsubscribe_date = models.DateTimeField(null=True, blank=True, db_index=True)在視圖中,我正在做的是遍歷所有 EmailLists 對象并獲取一些指標:以下方式:視圖.pyclass ListHealthView(View):    def get(self, request, *args, **kwargs):        start_date, end_date = get_dates_from_querystring(request)        data = []        for email_list in EmailList.objects.all():            # historic data up to start_date            past_contacts = email_list.contacts.filter(                status='active',                create_date__lt=start_date).count()            past_unsubscribes = email_list.customers.filter(                is_unsubscribed=True,                unsubscribe_date__lt=start_date,                contacts__status='active').count()            past_deleted = email_list.contacts.filter(                status='deleted',                modify_date__lt=start_date).count()            # data for the given timeframe            new_contacts = email_list.contacts.filter(                status='active',                create_date__range=(start_date, end_date)).count()            })        return Response({'data': data})現(xiàn)在這工作正常,但隨著 My DB 開始增長,此視圖的響應時間超過 1 秒,并且偶爾會導致數(shù)據(jù)庫中長時間運行查詢。我認為最明顯的改進是索引EmailList.customers,但我認為它可能需要一個復合索引?另外,有沒有更好的方法來做到這一點?也許使用聚合?
查看完整描述

1 回答

?
慕姐8265434

TA貢獻1813條經驗 獲得超2個贊

正如您的代碼為每個EmailList實例生成 6 個查詢一樣。對于 100 個實例,至少 600 個查詢會減慢速度。


您可以使用SubQuery()表達式和進行優(yōu)化.values()。


from django.db.models import Count, OuterRef, Subquery


data = (

    EmailList.objects

    .annotate(

        past_contacts=Count(Subquery(

            Contact.objects.filter(

                email_list=OuterRef('pk'),

                status='active',

                create_date__lt=start_date

            ).values('id')

        )),

        past_unsubscribes=...,

        past_deleted=...,

        new_contacts=...,

        new_unsubscribes=...,

        new_deleted=...,

    )

    .values(

        'past_contacts', 'past_unsubscribes',

        'past_deleted', 'new_contacts',

        'new_unsubscribes', 'new_deleted',

    )

)

更新:對于舊版本的 Django,您的子查詢可能需要如下所示


customers = (

    Customer.objects

    .annotate(

        template_count=Subquery(

            CustomerTemplate.objects

            .filter(customer=OuterRef('pk'))

            .values('customer')

            .annotate(count=Count('*')).values('count')

        )

    ).values('name', 'template_count')

)


查看完整回答
反對 回復 2022-05-24
  • 1 回答
  • 0 關注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號