繁体   English   中英

如何正确地在Django中遍历庞大的QuerySet?

[英]How to properly iterate over a huge QuerySet in django?

我需要检索5个符合特定复杂条件的对象,并且我希望/不希望将该条件传递给WHERE子句(django中的filter),所以我需要遍历结果,测试每个记录是否直到获得5个对象为止的条件,之后我要扔掉查询集,再也看不到它了。

在大多数情况下,我需要的记录将位于查询集的开头,在最坏的情况下,它将位于查询集的结尾。 桌子很大,我只需要5条记录。 所以我的问题是:如何在没有django缓存结果的情况下遍历查询集? 必须以这样一种方式来完成:sql引擎/ django都不会在任何地方存储/缓存结果。

您为什么担心缓存? 让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子句的操作可能会减慢您的速度,具体取决于查询集的大小。 只是要考虑的一件事。 我认为适当的基准测试应该可以为您提供方法。

Django没有全局缓存(请参阅故障单#14)。 这意味着只要您不保留任何内容,数据就会消失并且不再被缓存。 届时,垃圾收集器将在下一次清理时删除内存分配。 因此,代码如下:

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

在上面的特定实例中,唯一的缓存django将在此处执行,并且在此行之后,对缓存的任何引用都将消失。 请注意,如果Django没有任何缓存,则内存仍将以相同的方式填满,并且GC将以任何方式分别收集行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM