Se rilasci il SearchRank
e basta filtrare utilizzando la query, utilizzerà l'indice GIN e funzionerà molto, molto più velocemente:
query = SearchQuery(termo,config='portuguese')
entries = Article.objects.filter(search_vector=query)
Puoi aggiungere .explain()
per finire per dare un'occhiata alla query e vedere se l'indice è utilizzato:
print(entries.explain(analyze=True))
Dovresti vedere la query utilizzando Bitmap Heap Scan e il tempo di esecuzione dovrebbe essere molto più veloce.
Bitmap Heap Scan on your_table
...
Planning Time: 0.176 ms Execution Time: 0.453 ms
Quando annoti come se fossi sopra, stai annotando ogni Article
oggetto - quindi postgres decide di eseguire una Seq Scan (o Parallel Seq Scan) che ritiene più efficiente. Maggiori informazioni qui
Prova ad aggiungere .explain(verbose=True)
o .explain(analyze=True)
al tuo metodo iniziale di SearchRank per confrontare.
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))
Sto affrontando questo problema da solo, con una tabella con 990.000 voci che impiega circa 10 secondi. Se riesci a filtrare la query prima dell'annotazione utilizzando qualsiasi altro campo, il pianificatore di query tornerà a utilizzare l'indice.