过滤prefetch_related()以优化数据集

时间:2017-03-07 19:05:10

标签: django optimization

我在概述页面遇到了性能问题,正在寻求帮助。

下面是我当前的查询工作正常:页面在不到2秒的时间内呈现,总共n = 12个查询。到目前为止很棒。

person_occurrences = Occurrence.objects\
    .filter(date__year=first_day_in_month.year, date__month=first_day_in_month.month,
            real_time_in__isnull=False, real_time_out__isnull=False)\
    .distinct('person')

present_persons = Person.objects.filter(occurrence__in=person_occurrences).order_by('last_name')\
    .prefetch_related('occurrence_set') \
    .prefetch_related('fooindex_set') \
    .prefetch_related('servicevoucher_set')\
    .prefetch_related('stay_set__hospitalization_set') \
    .prefetch_related('invoice_set')

但是我需要在occurrence_set下访问另一个嵌套模型:

    .prefetch_related('occurrence_set__meal_noon_options') \
    .prefetch_related('occurrence_set__meal_noon_partner_options')

当我添加这两个内容时,我的页面会占用 25秒来加载n = 14个查询。

调试时(django-debug-toolbar),我注意到后者执行的查询是:

  

SELECT•••FROM" stay_mealoption"内部联接   " edc_occurrence_meal_noon_options" ON(" stay_mealoption"。" id" =   " edc_occurrence_real_meal_noon_options"。" mealoption_id")WHERE   " edc_occurrence_real_meal_noon_options"" occurrence_id" IN(32930,   32931,32932,32933,32934,32935,32936,32937,32938,32939,32940,   32941,32942,32943,32944,32945,32946,32947,32948,32949,32950,   32951,32952,32953,32954,32955,32956,32957,32958,32959,32960,   32961,32962,32963,32764,32965,32966,32967,32968,32969,32970,   32971,32972,33773,32974,32975,32976,32977,32978,32979,32980,   32981,32982,32983,32984,32985,32986,32987,32988,32989,32990,   32991等。

events_id显然是我的数据库中存在的所有 ID,目前超过10.000。因此,返回的数据集巨大并且正在减慢页面速度。

我尝试通过在第二个查询中过滤年/月来限制事件,即Person.objects.filter(occurrence__in=person_occurrences, occurrence__date__month=first_day_in_month.month, occurrence__date__year=first_day_in_month.year).order_by('last_name')\ <snip>,但这不起作用:prefetch_related()仍然提取所有occurrence个对象

我也查看了Django 1.7 +的Prefetch()个对象:

.prefetch_related(Prefetch('occurrence_set__meal_noon_partner_options',
                           queryset=occurrence.objects.filter(date__month=first_day_in_month.month, date__year=first_day_in_month.year))) \
.prefetch_related(Prefetch('occurrence_set__meal_noon_partner_options',
                           queryset=occurrence.objects.filter(date__month=first_day_in_month.month, date__year=first_day_in_month.year)))

...但我收到的投诉是,查询集不应该是Occurrence,而应该是MealOption

关于如何正确优化的任何想法?

使用Postgresql和Django 1.10。

0 个答案:

没有答案