代码之家  ›  专栏  ›  技术社区  ›  espenhogbakk

Django objects.filter,这会有多“昂贵”?

  •  1
  • espenhogbakk  · 技术社区  · 17 年前

    我正在尝试在Django中创建搜索视图。这是一个搜索表单,带有自由文本输入+一些选项可供选择,以便您可以根据年份等进行筛选。这是到目前为止我在视图中看到的一些代码,执行过滤的部分。我想了解一下这在数据库服务器上的开销。

    soknad_list = Soknad.objects.all()

    if var1:
        soknad_list = soknad_list.filter(pub_date__year=var1)
    
    if var2:
        soknad_list = soknad_list.filter(muncipality__name__exact=var2)
    
    if var3:
        soknad_list = soknad_list.filter(genre__name__exact=var3)
    
    # TEXT SEARCH
    stop_word_list = re.compile(STOP_WORDS, re.IGNORECASE)
    search_term = '%s' % request.GET['q']
    cleaned_search_term = stop_word_list.sub('', search_term)
    cleaned_search_term = cleaned_search_term.strip()
    if len(cleaned_search_term) != 0:
        soknad_list = soknad_list.filter(Q(dream__icontains=cleaned_search_term) | Q(tags__icontains=cleaned_search_term) | Q(name__icontains=cleaned_search_term) | Q(school__name__icontains=cleaned_search_term))
    

    这正是我想要的,但我想有一个更好/更聪明的方法来做到这一点。有什么想法吗?

    3 回复  |  直到 13 年前
        1
  •  4
  •   hasen    17 年前

    过滤器本身不执行查询,在您显式地从查询(例如get)中获取项之前,不会执行任何查询,而list(查询)也会执行查询。

        2
  •  2
  •   Aaron    17 年前

    您可以使用以下命令查看将生成的查询:

    soknad_list.query.as_sql()[0]
    

        3
  •  -1
  •   Jeremiah Peschka    17 年前

    如果我没有看错您的问题,那么您正在检索Soknad表中所有行的结果集。返回这些结果后,您可以使用filter()方法对符合条件的结果进行精简。从Django文档来看,这将执行内存中的筛选,而不是重新查询数据库(当然,这实际上取决于您使用的是哪个数据访问层,而不是Django本身)。

    与所有涉及数据库的事情一样,真正的答案是“视情况而定”。最好的建议是使用接近生产的数据尝试几种不同的方法,并在确定问题的最终解决方案之前,在至少3次迭代中对其进行基准测试。在内存中过滤可能与在数据库中过滤一样快,甚至更快。