Django查询速度极慢

时间:2013-07-31 12:37:01

标签: django database performance django-queryset django-postgresql

我遇到了Django应用程序的问题。模型 Scope 上的查询极其缓慢,经过一些调试后我仍然不知道问题出在哪里。

当我在django中查询像scope = Scope.objects.get(pk='Esoterik I')这样的数据库时,需要5到10秒。该数据库的主键少于10个条目和索引。所以这太慢了。在像SELECT * FROM scope WHERE title='Esoterik I';这样的数据库上执行等效查询时,一切正常,只需要大约50毫秒。

如果我使用scope_list = Scope.objects.filter(members=some_user)等一组结果进行查询,然后执行此操作,则会出现同样的问题打印(scope_list)或迭代列表的元素。查询本身只需要几毫秒,但元素的打印或迭代再次需要5到10秒,但该集只有两个条目。

数据库后端是Postgresql。问题在本地开发服务器和apache上发生相同。

这里是模型的代码:

class Scope(models.Model):
    title = models.CharField(primary_key=True, max_length=30)

    ## the semester the scope is linked with
    assoc_semester  =   models.ForeignKey(Semester, null=True) 

    ## the grade of the scope. can be Null if the scope is not a class
    assoc_grade     =   models.ForeignKey(Grade, null=True)

    ## the timetable of the scope. can be null if the scope is not direct associated with a class
    assoc_timetable =   models.ForeignKey(Timetable, null=True)

    ## the associated subject of the scope
    assoc_subject   =   models.ForeignKey(Subject)

    ## the calendar of the scope
    assoc_calendar  =   models.ForeignKey(Calendar)

    ## the usergroup of the scope
    assoc_usergroup =   models.ForeignKey(Group)

    members = models.ManyToManyField(User)

    unread_count = None

更新 这里是python profiler的输出。看来query.py被称为160万次有点太多了。 python profiler output

2 个答案:

答案 0 :(得分:3)

您应该尝试先解决问题。运行manage.py shell并运行以下命令:

scope = Scope.objects.get(pk='Esoterik I')
print scope

现在django查询不会被执行,直到他们非常必须。也就是说,如果您在第一行之后遇到缓慢,则问题出现在查询的创建中,这将表明对象管理器存在问题。下一步是尝试通过django执行原始SQL,并确保问题确实与管理器有关,而不是django中的错误。

如果您在第二行遇到速度缓慢,则问题可能是查询的实际执行,也可能是数据的显示\打印。您可以强制执行查询而不打印它(查看文档)以找出它是哪一个。

据我所知,但我认为解决这个问题的最佳方法是将过程分解为不同的部分并找出造成缓慢的部分

答案 1 :(得分:1)

为确保数据库执行时间,最好测试Django生成的查询,因为Django生成的查询可能不是简单的SELECT * from blah blah

要查看Django生成的查询:

_somedata = Scope.objects.filter(pk='Esoterik I') # you must use filter in here
print somedata.query.__format__('')

这将显示Django生成的完整查询。然后复制它并打开Postgresql控制台并使用Postgresql分析工具:

EXPLAIN ANALYZE <your django query here>;

像:

EXPLAIN ANALYZE SELECT * FROMsomeapp_scope WHERE id = 'Esoterik I';

EXPLAIN将显示平均执行数据,而ANAYLZE也会显示一些有关该分析执行时间的额外数据。

您还可以查看postgresql在查询执行期间是否在这些分析结果中使用了任何索引。