簡體   English   中英

如何在views.py上優化Django SQL SELECT查詢?

[英]How to optimize Django SQL SELECT Query on views.py?

這些是視圖中涉及的模型:

class Movie(models.Model):
    title_original = models.CharField(max_length=300,
                                      db_column='titulooriginal')
    title_translated = models.CharField(max_length=300, blank=True,
                                       db_column='titulotraducido')
    thumbnail = models.CharField(max_length=300, blank=True,
                                 db_column='imagen')
    length = models.CharField(max_length=75, db_column='duracion')
    rating = models.CharField(max_length=75, db_column='censura')
    genre = models.CharField(max_length=75, db_column='genero')
    country_of_origin = models.CharField(max_length=150, db_column='pais')
    trailer = models.CharField(max_length=300, blank=True, db_column='trailer')
    synopsis = models.CharField(max_length=3600, blank=True,
                                db_column='sinopsis')
    cast = models.CharField(max_length=300, blank=True, db_column='elenco')
    director = models.CharField(max_length=150, db_column='director')
    slug = models.SlugField(unique=True, blank=True)
    tsc = models.DateTimeField(auto_now=False, auto_now_add=True, db_column='tsc', null=True)
    tsm = models.DateTimeField(auto_now=True, auto_now_add=True, db_column='tsm', null=True)

    class Meta:
        db_table = u'peliculas'

    def __unicode__(self):
        return self.title_original


class ShowTime(models.Model):
    LANGUAGE_ESPANOL = 'Espanol'
    LANGUAGE_SUBTITLED = 'Subtitulada'
    LANGUAGE_CHOICES = (
        (LANGUAGE_ESPANOL, LANGUAGE_ESPANOL),
        (LANGUAGE_SUBTITLED, LANGUAGE_SUBTITLED))

    movie = models.ForeignKey(Movie, db_column='idpelicula')
    theater = models.ForeignKey(Theater, db_column='idcine',
                                      null=True)
    time = models.TimeField(null=True, db_column='hora')
    type_3d = models.NullBooleanField(db_column=u'3d')
    type_xd = models.NullBooleanField(null=True, db_column='xd')
    type_gtmax = models.NullBooleanField(null=True, db_column='gtmax')
    type_vip = models.NullBooleanField(null=True, db_column='vip')
    type_imax = models.NullBooleanField(null=True, db_column='imax')
    language = models.CharField(max_length=33, blank=True, db_column='idioma',
                                choices=LANGUAGE_CHOICES,
                                default=LANGUAGE_ESPANOL)
    city = models.ForeignKey(City, db_column='idciudad')
    start_date = models.DateField(blank=True, db_column='fecha_inicio')
    end_date = models.DateField(blank=True, db_column='fecha_fin')
    visible = models.NullBooleanField(null=True, db_column='visible')
    tsc = models.DateTimeField(auto_now=False, auto_now_add=True, db_column='tsc', null=True)
    tsm = models.DateTimeField(auto_now=True, auto_now_add=True, db_column='tsm', null=True)

    class Meta:
        db_table = u'funciones'

    def __unicode__(self):
        return (unicode(self.theater) + " " + unicode(self.movie.title_original) + " " +         unicode(self.time))

另外,這是查詢模型的視圖:

def list_movies(request, time_period):
    city = utils.get_city_from_request(request)

    if time_period == 'proximas-dos-horas':
        (start_date,
         end_date,
         hours_start,
         hours_end) = utils.get_datetime_filters_from_time_period(time_period)
    else:
        (start_date,
         end_date) = utils.get_datetime_filters_from_time_period(time_period)

    if not start_date:  # 404 for invalid time periods
        raise Http404

    movies = Movie.objects.filter(
        showtime__city=city.code,
        showtime__visible=1,
        ).order_by('-tsm').distinct()

    if time_period == 'proximas-dos-horas':
        movies = movies.filter(
            showtime__start_date__lte=start_date,
            showtime__end_date__gte=end_date,
            showtime__time__range=(hours_start, hours_end))

    elif time_period == 'proximos-estrenos':
        movies = movies.filter(
            showtime__start_date=None,
            showtime__end_date=None,
            )

    else:
        movies = movies.filter(
            showtime__start_date__lte=start_date,
            showtime__end_date__gte=end_date)

    context = {'movies': movies, 'city': city, 'time_period': time_period}
    return render_to_response('list_movies.html', context,
                              context_instance=RequestContext(request))

當前,此視圖消耗了數據庫中的大量資源,這導致瀏覽器上的Web事務響應時間很短。 我將應用程序與New Relic監視軟件連接起來,以分析應用程序和數據庫級別的事務。 這是我得到的跟蹤詳細信息:

在此處輸入圖片說明

我想獲得關於優化此視圖的somo建議,以便將數據庫資源的消耗降至最低

非常感謝!

我不知道您遇到的問題,但是我的2條建議是:

首先,考慮數據模型中的一些更改。 ShowTime類具有City的外鍵和Theater的外鍵,這似乎有點多余。 就個人而言,我更喜歡對地址進行非規范化,例如:

class Theater(models.Model):
    name = models.CharField(max_length=48)
    # Location fields.
    geo_country = models.CharField(max_length=48)
    geo_country_code = models.CharField(max_length=2)
    geo_locality = models.CharField(max_length=48)
    geo_street = models.CharField(max_length=48, blank=True, default="")
    geo_address = models.CharField(max_length=120, blank=True, default="")


class ShowTime(models.Model):
    theater = models.ForeignKey(Theater) 

這樣,您可以將JOIN保存到City表中,並且可以從數據模型中將其刪除。

其次,閱讀Django ORM的select_related功能

祝你玩得開心。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM