Ако изпуснете SearchRank
и просто филтрирайте с помощта на заявката, тя ще използва GIN индекса и ще работи много, много по-бързо:
query = SearchQuery(termo,config='portuguese')
entries = Article.objects.filter(search_vector=query)
Можете да добавите .explain()
за да завършите, за да разгледате заявката и да видите дали се използва индексът:
print(entries.explain(analyze=True))
Трябва да видите заявката, използваща Bitmap Heap Scan и времето за изпълнение трябва да е много по-бързо.
Bitmap Heap Scan on your_table
...
Planning Time: 0.176 ms Execution Time: 0.453 ms
Когато правите анотации, както сте по-горе, вие анотирате всеки Article
обект - така че postgres решава да извърши Seq Scan (или Parallel Seq Scan), което реши, че е по-ефективно. Повече информация тук
Опитайте да добавите .explain(verbose=True)
или .explain(analyze=True)
към вашия първоначален метод SearchRank за сравнение.
query = SearchQuery(termo,config='portuguese')
search_rank = SearchRank(F('search_vector'), query)
entries = Article.objects.annotate(rank=search_rank).filter(search_vector=query).order_by('-rank')
print(entries.explain(analyze=True))
Аз самият се сблъсквам с този проблем, с таблица с 990k записа, която отнема ~10 секунди. Ако можете да филтрирате заявката преди пояснението с помощта на други полета - това ще тласне планировчика на заявки обратно към използването на индекса.
От този отговор