django查询中or-ing Q对象的性能影响
Posted
技术标签:
【中文标题】django查询中or-ing Q对象的性能影响【英文标题】:Performance impact of or-ing Q objects in django query 【发布时间】:2015-03-03 13:33:08 【问题描述】:我正在执行一个将一堆 Q 组合在一起的查询,这似乎需要很多时间。这是一些伪代码
query_params = []
for i in range(80): #there are about 80ish Q objects being created
query_params.append(Q(filter_stuff))
那我还是他们一起
query_params = reduce(or_, query_params)
当我执行查询时
query = list(MyModel.objects.filter(query_params))
它挂了很长时间。我知道这是一个非常笼统的问题,如果不深入了解数据结构(在这里很难给出),就很难给出诊断。但我只是好奇在 django 查询中 or-ing Q
对象是否存在固有的性能影响
【问题讨论】:
你在谈论将 80 个条件组合在一起,无论如何这都会很慢......我建议找出一种更好的方法来查询你想要的记录 @doniyor 不,模型的字段很少,但我试图找到它们的特定对(即 q1 = Q(field1=val1, field2=val2), q2 = Q(field1=val3, field2=val4) 等...) 我建议创建配对索引。 调用 Django shell 并试用您的代码。我的猜测是对数据库的实际调用真的很慢,其余的代码并没有那么多。无论如何,如果您遇到性能问题:分析您的代码,看看哪一行很慢。 Warath-coder 对索引的看法可能是正确的,但请确保在整个代码中保持相同的顺序:如果您在(field1, field2)
上创建索引,则应该在 Q(field1=..., field2=...)
上查询,而不是在 Q(field2=..., field1=...)
上查询,否则复合索引获胜不行。
您是否尝试过调试工具栏来查看您正在生成的 SQL 以及实际需要多长时间?现在 80 个条件太疯狂了^^,你能告诉我们(没有代码)你想要实现什么。一定有更好/更简单的方法。
【参考方案1】:
能够通过减少Q
objects 的数量来显着缩短查询的长度。它们都是这样的格式:
q1 = Q(field1=field1_val1, field2=field2_val1)
q2 = Q(field1=field1_val2, field2=field2_val2)
#...etc
我最终将它们按 field1 值分组:
q_dict = field1_val1: [all field_2 values paired with field1_val1], ...
然后我的 q 个对象看起来像这样:
for field1_val, field2_vals = q_dict.items():
query_params.append(Q(field1=field1_val, field2__in=field2_vals))
这最终显着减少了我的 Q
对象数量,并且查询运行得更快
【讨论】:
以上是关于django查询中or-ing Q对象的性能影响的主要内容,如果未能解决你的问题,请参考以下文章