使用mysql最新版本django:
我有一个非常复杂的django查询,它运行得非常快——直到我添加了一个带有布尔字段的“and”——如下所示:
queriedForms = queryFormtype.form_set.filter(is_public=True)
newQuery = queriedForms.filter(formrecordattributevalue__record_value__icontains=term['TVAL'], formrecordattributevalue__record_attribute_type__pk=rtypePK)
newQuery = newQuery.filter(flagged_for_deletion=False)
logger.info(newQuery.query)
term['count'] = newQuery.count()
如果我去掉首字母“is\u public=true”或最后一个“flagged\u for\u deletion=false”,它的运行速度会非常快。如果将两者都用作过滤器,则count()函数的时间会增加大约2000%
不同的queryset.query输出如下:
SELECT `maqluengine_form`.`id`, `maqluengine_form`.`form_name`, `maqluengine_form`.`form_number`, `maqluengine_form`.`form_geojson_string`, `maqluengine_form`.`hierarchy_parent_id`, `maqluengine_form`.`is_public`, `maqluengine_form`.`project_id`, `maqluengine_form`.`date_created`, `maqluengine_form`.`created_by_id`, `maqluengine_form`.`date_last_modified`, `maqluengine_form`.`modified_by_id`, `maqluengine_form`.`sort_index`, `maqluengine_form`.`form_type_id`, `maqluengine_form`.`flagged_for_deletion` FROM `maqluengine_form` INNER JOIN `maqluengine_formrecordattributevalue` ON (`maqluengine_form`.`id` = `maqluengine_formrecordattributevalue`.`form_parent_id`) WHERE (`maqluengine_form`.`form_type_id` = 319 AND `maqluengine_form`.`is_public` = True AND `maqluengine_formrecordattributevalue`.`record_value` LIKE %seal% AND `maqluengine_formrecordattributevalue`.`record_attribute_type_id` = 18510 AND `maqluengine_form`.`flagged_for_deletion` = False)
SELECT `maqluengine_form`.`id`, `maqluengine_form`.`form_name`, `maqluengine_form`.`form_number`, `maqluengine_form`.`form_geojson_string`, `maqluengine_form`.`hierarchy_parent_id`, `maqluengine_form`.`is_public`, `maqluengine_form`.`project_id`, `maqluengine_form`.`date_created`, `maqluengine_form`.`created_by_id`, `maqluengine_form`.`date_last_modified`, `maqluengine_form`.`modified_by_id`, `maqluengine_form`.`sort_index`, `maqluengine_form`.`form_type_id`, `maqluengine_form`.`flagged_for_deletion` FROM `maqluengine_form` INNER JOIN `maqluengine_formrecordattributevalue` ON (`maqluengine_form`.`id` = `maqluengine_formrecordattributevalue`.`form_parent_id`) WHERE (`maqluengine_form`.`form_type_id` = 319 AND `maqluengine_form`.`is_public` = True AND `maqluengine_formrecordattributevalue`.`record_value` LIKE %seal% AND `maqluengine_formrecordattributevalue`.`record_attribute_type_id` = 18510)
第一种方法大约需要20/30秒来执行count(),而第二种方法只有两个booleanfield中的一个,执行count()所需的时间不到一秒
==========================================================编辑================================抱歉:既然问题不够明显--为什么添加一个额外的and和一个布尔字段会将查询时间增加+2000%?有没有人能帮忙找出原因。谢谢。
1条答案
按热度按时间klr1opcd1#
编辑=========================
还发现使用排除(is\u public=false)而不是筛选器(is\u public=true)与下面的解决方案具有相同的效果。有人知道为什么exclude()可以正常工作,而filter()不行吗?
我休息了一晚上后想出了解决办法:
--我保持查询的原样(我以后需要它,因为它会继续进行链式筛选)--我需要这个阶段的count()--这比使用额外的booleanfield花费的时间要长得多--我需要一个临时值列表来执行len():
在使用相同的技术之后,使用链式过滤器的计数要快得多,如果没有从过滤器中删除一个布尔值那么快的话。