2015-06-30 10 views
5

Mam problem z wydajnością podczas renderowania szablonu django z zestawem zapytań z wyprzedzeniem, który nie jest zbyt duży (~ 1000 obiektów w środowisku produkcyjnym/~ 200 obiektów w środowisku projektowania), ale ma kilka poziomów zagnieżdżania.Szybkość renderowania szablonów Django

Oto prefetch:

stories = Story.objects.select_related(
      'commande', 
      'commande__societe', 
      'commande__plateforme', 
      'client',).prefetch_related(
      Prefetch('crm_message_related', 
        queryset=Message.objects.select_related(
         'societe', 
         'plateforme', 
         'type_message').order_by('-date_received')), 
      Prefetch('commande__crm_feedback_related'), 
      Prefetch('commande__crm_guarantee_related'), 
      Prefetch('commande__soyouz_item_related', 
        queryset=Item.objects.select_related(
         'etat', 'produit', 'produit__produit_enhanced',)), 
      Prefetch('commande__tagged_items__tag'), 
      Prefetch('commande__soyouz_item_related__tagged_items__tag'), 
      Prefetch('commande__soyouz_item_related__soyouz_annulationclient_related'), 
      Prefetch('commande__soyouz_item_related__soyouz_achat_related'), 
      Prefetch('commande__soyouz_item_related__soyouz_achat_related__soyouz_receptionachat_related'), 
      Prefetch('commande__soyouz_item_related__soyouz_achat_related__soyouz_annulationachat_related'), 
      Prefetch('soyouz_action_related'), 
      Prefetch('soyouz_action_related__receptionmessage__message', 
        to_attr='receptionmessages', 
        queryset=Message.objects.order_by(
         '-date_received').select_related(
         'societe', 'type_message', 'plateforme')) 
     ).order_by(
      '-commande__date_commande', 
      '-date_created' 
     ).all().distinct() 

Bieg SQL płynnie, nie to jest to problem.

Problem jest, gdy próbuję uczynić mój szablon czarownica jest basicaly

{% for story in stories %} 
    {% with items=story.commande.soyouz_item_related.all %} 
    {% for item in items %} 
     {% for tag in item.tagged_items.all %} 
      <button>{{ tag.tag }}</button> 
     {% endfor %} 
     {{ item.titre|safe|truncatechars:50 }} 
    {% endfor %} 
{% endfor %} 

To trwa około 10 sekund, aby wyświetlić stronę w środowisku produkcyjnym.

I profilowane w moim środowisku programistycznym z django-template-Timing (https://github.com/orf/django-debug-toolbar-template-timings) i rzeczywiście:

name   Times Tot Time Queries Queries Time 
stories.html 1  2814,1 ms 0   0 ms 

3 sekundy dla 3 pętle z 200 danych (w środowisku programowania)? Wydaje się dużo.

Wszelkie pomysły na zwiększenie szybkości renderowania szablonu?

Wielkie dzięki!

+0

Czy próbowałeś z 'DEBUG = False'? Język szablonów Django nie jest znany ze swojej szybkości, ale wydaje się to przesadne i nie wierzę, że pętle-lo są szczególnie powolne.Dla pewności: czy mówisz o 200 historiach, tagach, całkowitych przedmiotach? – knbk

+0

w dev: 200 opowiadań - 1 element na historię - 0 tagów na artykuł w języku prod: 1000 artykułów - 1 lub 2 elementy na historię - 1 tag na artykuł – Tigrou

+0

DEBUG = Fałsz jest już ustawiony w środowisku produkcyjnym – Tigrou

Odpowiedz

0

Użyj niestandardowego znacznika i wygeneruj dane wyjściowe poza szablonem. Pomoże to uniknąć narzutu na szablon django.

5

Chociaż django-template-timing zgłasza czas renderowania na 2,8 s, podejrzewam, że większość czasu jest zużywana podczas wykonywania złożonego zapytania SQL.

W Django, QuerySets are evaluated lazily. Oznacza to, że instrukcja wysłana przez użytkownika Story.objects.select_related(...).distinct() NIE wykonuje kwerendy w bazie danych. SQL zostanie wykonany later. Ponieważ nie opublikowałeś całego kodu przed renderowaniem szablonu, nie jestem pewien, czy QuerySet zostanie oceniony przed renderowaniem. Jeśli nie, to może być wykonywane podczas iteracji stories w szablonie:

{% for story in stories %} 

jeśli jest to przypadek, to może poprawy SQL może zmniejszyć czas.

Można sprawdzić, czy wykonanie SQL jest winowajcą, wstawiając to przed renderowania szablonu:

stories = [story for story in stories] 

Ta iteracja dostaje SQL wykonywane przed renderowania. Następnie, jeśli django-template-timing zgłasza znacznie krótszy czas renderowania, wiesz, że SQL jest problemem.

Jeśli to rzeczywiście szablon renderowania problem wydajność, istnieje kilka alternatyw:

  1. użyć bardziej wydajnych silnik szablonu, jak Jinja2.
  2. Istnieje szansa na poprawę wydajności renderowania dzięki szablonowi Django: https://stackoverflow.com/a/26592207/954376.
+0

Znaleźliśmy najlepsze rozwiązanie : jinja + paginacja, gdy to możliwe – chocobn69