python - 如何优化此 Django View 的 SQL?

标签 python sql django query-optimization

我正在编写一个 Django View ,该 View 从数据库中查询对象列表以及相关字段中的一些信息。问题是数据库正在对 7 个对象执行 10 次查询。代码如下:

模板代码:

{% for resource in results %}
    <li>
        <a href="{{resource.url}}"> {{resource.url}}
                 {{resource.stats_set.values.0.avg}}</a>
<!-- truncated, the rest of the template just generates a form and 
 isn't causing any unnecessary sql -->
{% endfor %}

查看代码:

class ResourceList(generic.ListView):
    model = Submissions
    context_object_name = 'results'
    template_name = 'url_list.html'

以及必要的模型:

class Submissions(models.Model):
    LEVEL = (
        ('Introductory', 'Introductory'),
        ('Intermediate', 'Intermediate'),
        ('Academic', 'Academic'),
    )

    MEDIA_TYPE = (
        ('HTML', 'HTML'),
        ('PDF', 'PDF'),
        ('Video', 'Video'),
        ('Other', 'Other'),
    )
    id = models.AutoField(primary_key=True)
    url = models.URLField(unique=True)
    tags = models.ForeignKey(MajorTags, default=0)
    level = models.CharField(choices=LEVEL, max_length=25)
    media_type = models.CharField(choices=MEDIA_TYPE, max_length=25)

    def __unicode__(self):
        return self.url

    def __str__(self):
        return self.url

class Stats(models.Model):
    url = models.ForeignKey(Submissions)
    id = models.AutoField(primary_key=True)
    avg = models.FloatField(default=0)
    std_dev = models.FloatField(default=0)

    def __unicode__(self):
        return self.url.url + " " + str(self.avg)

    def __str__(self):
        return self.url.url + " " + str(self.avg)

问题的根源在于 {{resource.stats_set.values.0.avg}} 位。问题是,如果我尝试执行 queryset = Submissions.objects.all().select_lated('avg') ,我会收到一条错误消息,指出唯一的选项是 select_lated() code> 是 tags ,这是有道理的,因为这是 Submissions 模型中唯一具有外键的字段。此时我的数据库结构已相当锁定,因此我无法更改数据库。我也无法查询统计信息并从那里执行相反的操作,因为我需要获取尚无统计信息的数据。

如何减少正在运行的 SQL 查询数量?

最佳答案

您应该使用prefetch_related它用于对反向外键或多对多关系进行有效查询:

来自文档:

prefetch_related()

Returns a QuerySet that will automatically retrieve, in a single batch, related objects for each of the specified lookups.

def get_queryset(self,*args,**kwargs):
     return Submissions.objects.all().prefetch_related('stats_set')

这将需要额外的查询,但其想法是它将立即获取所有相关信息,而不是每个 Submissions 对象获取一次。

顺便说一句,建议使用名词的单数作为模型类名称:Submission 而不是 Submissions

关于python - 如何优化此 Django View 的 SQL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33831389/

相关文章:

python - 在 Dreamhost 上调试 Django/Python

django - API监控工具

python ,Tkinter : How to get the handle of all canvas objects using their IDs or tags?

python - 为什么 pip 在 vi​​rtualenv 中写入/usr/lib?

mysql - 更新列值,替换字符串的一部分

SQL 查询 : how to get users and their three latest posts?

python - django:自定义 token 认证

python - 什么在这个 python 代码(谷歌应用引擎)中产生 "405 Method Not Allowed"?

python - 将输入列表中的字典元素附加到元组列表

sql - 如何使用转换在 INFORMATICA 中创建一系列日期范围?