Si vous supprimez le SearchRank
et filtrez simplement à l'aide de la requête, il utilisera l'index GIN et fonctionnera beaucoup, beaucoup plus rapidement :
query = SearchQuery(termo,config='portuguese')
entries = Article.objects.filter(search_vector=query)
Vous pouvez ajouter .explain()
à la fin pour jeter un œil à la requête et voir si l'index est utilisé :
print(entries.explain(analyze=True))
Vous devriez voir la requête utilisant Bitmap Heap Scan et le temps d'exécution devrait être beaucoup plus rapide.
Bitmap Heap Scan on your_table
...
Planning Time: 0.176 ms Execution Time: 0.453 ms
Lorsque vous annotez comme ci-dessus, vous annotez chaque Article
object - donc postgres décide d'effectuer un Seq Scan (ou Parallel Seq Scan) qu'il juge plus efficace. Plus d'informations ici
Essayez d'ajouter .explain(verbose=True)
ou .explain(analyze=True)
à votre méthode SearchRank initiale pour comparer.
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))
Je suis moi-même confronté à ce problème, avec une table avec 990 000 entrées qui prend environ 10 secondes. Si vous pouvez filtrer la requête avant l'annotation en utilisant d'autres champs, cela repoussera le planificateur de requêtes vers l'utilisation de l'index.