【问题标题】:Minimize mysql database hits from django query最小化来自 django 查询的 mysql 数据库命中
【发布时间】:2010-11-07 16:39:36
【问题描述】:

我在 django 中进行查询,最终访问数据库 4 次。我想确定没有比我已经在做的更有效的数据提取方式了。

我有一个模型:

class Film(models.Model):
   studio = models.ForeignKey(Studio)
   name = models.CharField(max_length=30)
   rating = models.ForeignKey(Rating)
   actor = models.ManyToManyField('Actor', blank=True, related_name='actor', db_table=u'moviedb_film_actor')
   staff = models.ManyToManyField(Staff, blank=True, through='Association')

我的观点在这里:

def film_by_id(request, id):

   # Look up the car name (and raise a 404 if it can't be found).
   object = get_object_or_404(film.objects.select_related(), id__iexact=id)

   template_name = 'Film_by_id.html',

   association_objects = Association.objects.select_related(depth=1).filter(Q(film__name=object.name))
   source_objects = Source.objects.filter(film__name=object.name)

   object.association_objects = association_objects
   object.trim_objects = trim_objects

   return render_to_response(
        template_name,
        {"object" : object},
        context_instance = RequestContext(request))

最后,我的模板:

Make: {{ object.studio }}<br>
Rating: {{ object.rating }}<br><br>

<u>--Actors--</u><br>
{% for actor in object.actor.all %}
    {{ actor.name }}<br>
{% endfor %}
<br>

<u>--Staff--</u><br>
{% for item in object.association_objects %}
    {{ item.staff.name }} - {{ item.get_type_display }}<br>
{% endfor %}

<u>--Source--</u><br>
<ul>
{% for item in object.source_objects %}
    <li>{{ item }}
{% endfor %}
</ul>

调试工具栏显示我正在访问数据库 4 次。问题似乎是 ManytoMany 字段和我尝试使用 Source 执行的“反向 select_related”。

所以初始数据拉取一次
引用 Actor 命中一次
引用 Association_objects 命中一次
引用源点击一次

所以总的来说,有没有办法减少数据库命中?具体来说,有没有更好的方法来拉取多对多关系,而无需创建更多的同时数据库查询?

【问题讨论】:

    标签: django mysql django-templates many-to-many


    【解决方案1】:

    如果您要在它们之间使用ForeignKey 关系,则可以消除对AssociationSource 的查找。然后select_related 也可以拉这些。

    如果您真的非常关心优化 ManyToManyField,我建议您缓存查找结果。

    【讨论】:

    • ForeignKey 不适用于 Association,因为此链接的数据性质是多对多,而不是多对一。而对于Source,我需要Source一侧的外键链接,而不是film。所以它就像 select_related,但据我了解,您不能从链接的另一侧使用 select_related。
    • 如果这个视图对数据库造成太大负担,那么缓存是可行的方法。
    • 您的意思是每个实例都有一个缓存吗?或者像内存缓存?您能否编辑您的答案并在该位上添加一些细节(也许是代码)?非常感谢!
    • 你可以缓存查询的结果,使用查询的视图,只是它的一部分,几乎任何你想要的,真的:docs.djangoproject.com/en/dev/topics/cache
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2019-03-30
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多