如何正确迭代django中的巨大QuerySet?

时间:2010-10-08 17:49:01

标签: python django django-queryset

我需要检索5个符合某个复杂条件的对象,我不能/不想将该条件传递给WHERE子句(在django中过滤),所以我需要迭代结果,测试每个记录的标准,直到我得到我的5个对象,之后我想抛出查询集,再也不会看到它。

在大多数情况下,我需要的记录将位于查询集的开头,在最坏的情况下,它将在最后。表很大,我只需要5条记录。所以我的问题是:如何在没有django缓存结果的情况下迭代查询集?这必须以sql engine / django在任何地方存储/缓存结果的方式完成。

2 个答案:

答案 0 :(得分:1)

为什么要担心缓存?让Django或mysql做他们做的事情。

如果你弯腰。您可以禁用Django的缓存。这在您的项目的settings.py中非常简单。

对于Mysql,您需要运行一些查询来禁用查询缓存 -

尝试在查询中使用SQL_NO_CACHE选项。像这样

SELECT SQL_NO_CACHE * FROM TABLE

这将阻止MySQL缓存结果,但请注意其他操作系统和磁盘缓存也可能会影响性能。这些更难以解决。

此方法的一个问题是它似乎只会阻止查询结果被缓存。但是,如果您要查询正在与要测试的查询一起使用的数据库,则其他客户端可能会缓存您的查询,从而影响您的结果。我正在继续研究解决这个问题的方法,如果我找到一个,我会编辑这篇文章。

你也可以RESET QUERY CACHE

FLUSH QUERY CACHE

虽然需要注意的一点是,我建议让Mysql处理WHERE子句,因为它有查询优化层,如果你有正确的字段索引,这将是非常有效的。获得所有结果&您执行WHERE子句所做的操作可能会降低您的速度,具体取决于查询集的大小。只是要考虑一些事情。我认为适当的基准测试应该为您指明方向。

答案 1 :(得分:0)

Django没有全局缓存(参见#14票证)。这意味着只要您不抓住任何内容,数据就会消失,不再被缓存。此时,垃圾收集器将在下次清理时删除内存分配。因此,代码如:

my_objects = [obj for obj in MyModel.objects.all() if my_complex_condition(obj)]

这里唯一的缓存django会在上面的特定实例中执行,在此行之后,对缓存的任何引用都将消失。请注意,如果Django没有任何缓存,内存仍将以相同的方式填充,GC将以任何方式单独收集行。