如何加快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跑得非常慢?
答案 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