Se você descartar o
SearchRank
e apenas filtrar usando a consulta, ele usará o índice GIN e terá um desempenho muito, muito mais rápido:query = SearchQuery(termo,config='portuguese')
entries = Article.objects.filter(search_vector=query)
Você pode adicionar
.explain()
para finalizar dê uma olhada na consulta e veja se o índice é usado:print(entries.explain(analyze=True))
Você deve ver a consulta usando Bitmap Heap Scan e o tempo de execução deve ser muito mais rápido.
Bitmap Heap Scan on your_table
...
Planning Time: 0.176 ms Execution Time: 0.453 ms
Quando você anota como está acima, você está anotando todas
Article
object - então o postgres decide realizar um Seq Scan (ou Parallel Seq Scan) que ele decide ser mais eficiente. Mais informações aqui
Tente adicionar
.explain(verbose=True)
ou .explain(analyze=True)
ao seu método SearchRank inicial para comparar. 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))
Estou enfrentando esse problema, com uma tabela com 990k entradas que leva ~ 10 segundos. Se você puder filtrar a consulta antes da anotação usando qualquer outro campo - isso fará com que o planejador de consulta volte a usar o índice.
De esta resposta