Векторный поиск с помощью PGVector занимает больше времени

Я использую PGVector в Django для создания векторного поиска. Время поиска совпадающей строки составляет несколько миллисекунд, код, который я использую для этого, выглядит так

embedding=self.get_input_embedding(inputText)
output=(
      table.objects.annotate(
            distance=CosineDistance("embedding",embedding)
      )
      .order_by(CosineDistance("embedding",embedding))
      .filter(distance__lt=1-threshold)[:2]
)

Выходная переменная имеет тип класса QuerySet. Теперь, чтобы получить из нее значение, я использую код

for neigh in output:
    print(neigh.Link)

Теперь этот блок занимает более 3 секунд. В чем может быть причина этого?

Ниже приведен простой воспроизводимый код.

Models.py

from django.db import models
from django.db import migrations
from pgvector.django import VectorField, VectorExtension 

class Migration(migrations.Migration):
    operations = [VectorExtension()]

class Question_match(models.Model):
    Title = models.TextField("Text")
    Link = models.TextField("Text")   
    Questions = models.TextField("Text")  
    Answers = models.TextField("Text") 
    embedding = VectorField(dimensions=1536)
    class Meta:
        db_table = "generated_question"

pipelines/retrieving_matches.py

from openai import OpenAI
from pgvector.django import CosineDistance

class EmbeddingMatch(object):

      def __init__(self):
            self.client = OpenAI()

      def get_input_embedding(self, input_query):
            return self.client.embeddings.create(input=([input_query]), 
                                                 model="text-embedding-3-small").data[0].embedding

      def predict(self, inputText,table,threshold=0.7,nresponse: int=2):
            embedding=self.get_input_embedding(inputText)
            records=[]
            output=(
                  table.objects.annotate(
                        distance=CosineDistance("embedding",embedding)
                  )
                  .order_by(CosineDistance("embedding",embedding))
                  .filter(distance__lt=1-threshold)[:2]
            )
            records.extend(
                  [
                        (neighbour.Title,neighbour.Link,neighbour.Questions,1-neighbour.distance)
                        for neighbour in output
                  ]
            )
            return records

apps.py

from question_answer.pipelines.retrieving_matches import EmbeddingMatch
class DirectMap(AppConfig):
    question_match = EmbeddingMatch()

views.py

from .models import Question_match

class get_question(APIView):
    def __init__(self):
        pass
    def post(self, request, *args, **kwargs):
        inputs = json.loads(request.body)
        # question is the query we want to get the answers for
        query = inputs.get("question")
        qwerty = DirectMap.question_match.predict(query, Question_match)
    .
    .
    .
    .

Я также попытался использовать SQL-запрос, используя соединения django, и все равно время ответа было высоким и занимало около 4-5 секунд.

query = """SELECT "Link"
            FROM generated_question
            ORDER BY embedding <=> %s::vector
            LIMIT 5"""
with connection.cursor() as cursor:
      cursor.execute(query, [vector_str])
      result = cursor.fetchall()

Django QuerySets являются lazy и оцениваются как documented

(query) ничего не делает, а запрос выполняется при итерации

Вернуться на верх