在一个过滤日期范围的基本QuerySet上执行不同次数的多个过滤器时,优化django数据库访问

时间:2011-01-30 20:16:14

标签: django django-models

我的观点是这样的:

objectBase = MyModel.objects.filter(startDate__range=(start,end))
automatedObjects = objectBase.filter(automated = True).count()
userCreatedObjects = objectBase.filter(userCreated = True).count()
bookObjects = objectBase.filter(subClass = 'book').count()
pageObjects = objectBase.filter(subClass = 'page').count()
allObjectsCount = objectBase.count()

我使用的是1.2.4和最新的postgres

无论如何,我有大约20种不同的方法来过滤按日期过滤的objectBase,我注意到每个SQL查询按日期过滤。是否有更有效的方法使后续查询不必按日期过滤?会有速度差吗?

另外你认为什么是缓存objectBase查询的最佳方法,因为理论上它可以为过滤的日期保存数百或数千个对象,并且开始的可能引擎,结束日期对于请求来说是相同的不太可能。

比如说有人可以在日期t1和t2之间请求统计数据,然后请求t3到t4,其中t1< t3< t2和t2< t4所以有一些重叠。有没有办法对它进行缓存,以便在它必须访问db的请求之间存在重叠?

抱歉,如果这似乎是一个沉重的请求,但任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

减少查询次数......

objectBase = MyModel.objects.filter(startDate__range=(start,end))
automated, user_created, books, pages, total = 0,0,0,0,0
for o in objectBase:
    if o.automated: automated += 1
    if o.userCreated: user_created += 1
    if o.subClass == 'book': books += 1
    if o.subClass == 'page': pages += 1
    total += 1

这只会执行一个查询,但它可能会慢于你已经在做的事情,具体取决于你的SQL索引。如果您指望的所有字段都被编入索引以及日期范围,那么您的解决方案将很快。我会怀疑你是否已将所有这些字段编入索引。

关于缓存的问题。没有使用相同的查询集实例,没有简单的方法来缓存查询集结果。您可以尝试使用django缓存框架,但如果您的表中有数千行,我认为缓存不会对您有所帮助。

我的建议是在日期范围涵盖的所有列上创建索引。这样可以使您的.count查询非常快,而无需迭代可能庞大的集合。

答案 1 :(得分:0)

除非遇到一些严重的性能问题,否则你应该这样做。创建查询集objectBase不会访问数据库,因为查询尚未执行。从数据库中检索所有对象并通过python / django缓存它们可能会消耗大量内存并降低性能。通过数据库/ SQL查询进行计数应该是获得结果的最快方法!