我正在使用Django 1.8。
我有一个需要逻辑"或"的查询集。和"和"。 它给出了:
MyModel.objects.filter(
Q(start__gt=today) | Q(end__lte=today),
active=True).update(active=False)
正如您可能了解的那样,它应该采取每个尚未启动的活动MyModel实例,以及已完成的实例,并停用它们。
"开始"和"结束"是DateFields,"活跃"是一个布尔值。
它可以工作,但它生成的查询远未被优化。我希望能够通过过滤" active"来启动查询。状态,然后检查其他两个字段,因为在我的数据库中,我有数千个条目,但只有少数有active = True。我会说这个布尔测试比比较更快。
我无法重新排序参数,因为前者带有两个Q()是一个定位参数而后者是一个名称参数,我不能链接多个filter()因为它生成一个"或",而不是"和"。
有办法做到这一点吗?
答案 0 :(得分:1)
首先,Django ORM生成的SQL命令可能没有条件子句与JSON.stringify()
方法的顺序相同。所以不要担心“最佳”订单。
其次,无论子句以何种顺序出现在SQL命令中,数据库引擎都会优化请求并生成适合您的数据分发的执行计划。任何值得考虑的数据库引擎都会保留一些数据分布如果.filter
记录的比例实际上是此查询中的最佳判别式,那么它将首先被过滤。
答案 1 :(得分:0)
active
首先过滤start
然后过滤end
和Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
,我认为您不会获得任何性能提升。因为chaning或 not -chaining将执行相同的查询。以下是Django docs的一个例子:
SELECT ... WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')
在SQL术语中,评估为:
if (Date.parse(currentDate) >= Date.parse(maxDate)) { alert('error'); }
请注意,过滤器已在上面的示例中链接,但在SQL查询中,两个过滤器都是一起使用的。
提升数据库性能
查找数据库索引(如注释中所示)。
考虑在内存中缓存数据库(例如,请参阅Memcached)。