2

你如何加速Haystack搜索驱动(使用 Whoosh 后端)分页的 Django 列表视图?

我有一个简单的 ListView,例如:

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

返回一个包含 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 运行缓慢?

4

2 回答 2

2

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

如果您想避免一般的数据库查找并且只显示被索引的数据(您也可以尝试这样做以确保缓慢是由额外的数据库查找引起的)。否则,如果您需要额外的调试,请使用debug-toolbar,它将显示所有数据库查询,并且还有一个额外的 haystack 面板。

于 2013-05-21T13:15:20.737 回答
1

根据这个 Haystack 问题,您可以做两件事。

第一个,可以在设置INCLUDE_SPELLINGFalse设置为,如下:

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
于 2016-01-25T18:06:06.690 回答