Django ListView使用Haystack的速度非常慢

时间:2013-05-21 13:02:59

标签: python django django-haystack

如何加快Haystack搜索功能(使用Whoosh后端)分页Django列表视图?

我有一个简单的ListView,如:

class PersonListView(ListView)
    template_name = 'person-list.html'
    paginated_by = 10
    def get_queryset(self):
        return Person.objects.all()

在我的localhost上返回一个包含3000个结果的页面大约1秒钟。

然后我“插入”Haystack以允许通过执行以下方式对名称进行全文搜索:

class PersonListView(ListView)
    template_name = 'person-list.html'
    paginated_by = 10
    def get_queryset(self):
        #return Person.objects.all()
        return SearchQuerySet().models(models.Person)

我设置了相应的索引并运行manage.py rebuild_index

class PersonIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    nickname = indexes.CharField()
    first_name = indexes.CharField()
    middle_name = indexes.CharField()
    last_name = indexes.CharField()

    def get_model(self):
        return models.Person

    def index_queryset(self, using=None):
        return self.get_model().objects.all()

然而,在此之后,同一页面现在需要大约15秒才能运行...

我尝试使用django profiler,但是在更改之前和之后的查询时间没有太大差异,并且运行时间最长的查询只需要一秒钟,表明视图端存在一些错误导致所有查询结果被迭代。

是什么原因导致Haystack跑得非常慢?

2 个答案:

答案 0 :(得分:2)

搜索速度慢的一个原因是,对于每个搜索结果,haystack将尝试从数据库中获取相应的对象。您可以使用SearchQuerySet上的load_all()来阻止此行为。然后haystack将尝试在一个查询中收集所有结果。在显示来自相关模型的内容时要小心,因为这将导致额外的数据库查找而无需任何其他配置。

如果您想要避免一般的数据库查找和only display data that is indexed(您也可以尝试这样做以确保缓慢是由附加数据库查找引起的)。 否则,如果您需要其他调试,请使用debug-toolbar,它将显示所有数据库查询,还有一个额外的干草堆面板。

答案 1 :(得分:1)

根据this Haystack issue,你可以做两件事。

第一个,您可以在设置中将INCLUDE_SPELLING设置为False,如下所示:

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'PATH': os.path.join(PATH_TMP, "whoosh_index", "default"),
        'STORAGE': 'file',
        'POST_LIMIT': 128 * 1024 * 1024,
        'INCLUDE_SPELLING': False,
        'BATCH_SIZE': 100,
    },
}

另一件事是您可以将HAYSTACK_ITERATOR_LOAD_PER_QUERY设置为更大的数字,例如100而不是默认的10

HAYSTACK_ITERATOR_LOAD_PER_QUERY = 100