【问题标题】:django accessing to models takes so much timedjango 访问模型需要很多时间
【发布时间】:2014-09-21 05:28:42
【问题描述】:

我有一个这样的模型:

class Event(models.Model):
    description = models.CharField(max_length=3072)
    severity = models.CharField(max_length=96)
    reception_timestamp = models.DateField()
    version = models.CharField(max_length=100)
    mail_archive_id = models.PositiveIntegerField()
    component_id = models.CharField(max_length=32)
    technician_at_work = models.BooleanField()
    timestamp = models.DateField(db_index=True)
    system = models.ForeignKey(System)
    event_code = models.ForeignKey(EventCode)

在我的 views.py 文件中,我尝试访问信息所在的 MySql 数据库。

我运行了一些 QuerySets 操作,然后我继续从模型中提取我需要的信息以将其呈现到 html 模板,但是提取信息花费了太多时间:

events = Event.objects.filter(system_id=system_id).filter(timestamp__range=[from_date, now])
return [ e.timestamp, e.system.serial_number, e.version, e.event_code.code, e.description, e.severity, e.reception_timestamp for e in events ]

我尝试了一些方法,例如创建一个生成器并将其发送到模板,以使用它呈现 HTML 文档,但访问信息所花费的时间相同。

我能做什么?只需一两分钟即可抓取 270 行。 我检测到查询需要几秒钟时间,但是是对信息的访问消耗了剩下的时间。我该如何提升它?

谢谢!

【问题讨论】:

    标签: python mysql django templates render


    【解决方案1】:

    两点:

    1) QuerySet 被延迟评估,因此它们的计时可能有点奇怪。 “events = Event.objects...”行是否需要几秒钟,或者您是否为查询集 plus 获取数据计时?后者看起来像这样:

    start = time.time()
    # build lazy queryset:
    events = Event.objects.filter(system_id=system_id).filter(timestamp__range=[from_date, now])
    # evaluate and flatten queryset:
    res = [ e.timestamp, e.system.serial_number, e.version, e.event_code.code, e.description, e.severity, e.reception_timestamp for e in events ]
    logging.info('query took %s', time.time()-start)
    

    2) 您可以使用 values_list() 方法让 QuerySet 直接为您输出字段,而不是单独的 for 循环。也就是说:

    events = Event.objects.filter(system_id=system_id).filter(timestamp__range=[from_date, now])
    event_vals = events.values_list('timestamp', 'system.serial_number') # more here
    return event_vals
    

    第一行构建了一个惰性查询集,描述你想要什么样的数据。第二行要求 Django 只给你一个元组列表。它为您重新排序和展平数据,并且可能比将所有行显式转换为模型,然后使用单独的循环提取数据更快。

    【讨论】:

    • 但是 values_list 函数不会获取外键值,是吗?与“system.serial_number”类似,以便访问“system”属性,然后查找“serial_number”值。
    • 我找到了!用双下划线 (__) 代替点 (.) 谢谢!
    猜你喜欢
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 2018-05-21
    相关资源
    最近更新 更多