Tig*_*rou 5 python django django-templates
我在使用预取查询集渲染django模板时遇到了性能问题,这个模板并不是很大(生产环境中约1000个对象/开发环境中约200个对象),但有几个嵌套级别.
这是预取:
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()
Run Code Online (Sandbox Code Playgroud)
SQL运行顺利,这不是问题.
问题是当我尝试渲染我的模板时,女巫是基本的
{% 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 %}
Run Code Online (Sandbox Code Playgroud)
在生产环境中显示页面大约需要10秒.
我用django-template-timing(https://github.com/orf/django-debug-toolbar-template-timings)在我的开发环境中对它进行了分析,的确如下:
name Times Tot Time Queries Queries Time
stories.html 1 2814,1 ms 0 0 ms
Run Code Online (Sandbox Code Playgroud)
3个循环,包含200个数据(在开发环境中)3秒?看起来很多.
有什么想法可以提高模板渲染的速度吗?
非常感谢!
虽然django-template-timing将渲染时间报告为2.8秒,但我怀疑大部分时间都是在执行复杂的SQL查询时消耗的.
在Django中,QuerySets被懒惰地评估.这意味着,您发布的语句Story.objects.select_related(...).distinct()不会在数据库中执行查询.SQL 稍后执行.由于在渲染模板之前没有发布所有代码,我不确定QuerySet是否在渲染之前得到了evalueted.如果没有,可以stories在模板中迭代时执行:
{% for story in stories %}
Run Code Online (Sandbox Code Playgroud)
如果是这种情况,那么改进SQL可能会减少时间.
您可以在渲染模板之前插入此项来检查SQL执行是否是罪魁祸首:
stories = [story for story in stories]
Run Code Online (Sandbox Code Playgroud)
此迭代获取在呈现之前执行的SQL.在此之后,如果django-template-timing报告的渲染时间要短得多,那么就知道SQL就是问题所在.
如果它确实是模板渲染性能问题,那么有一些替代方案:
| 归档时间: |
|
| 查看次数: |
2952 次 |
| 最近记录: |