0Pricing
AI Engineering Academy · Lektion

pgvector: Embeddings in PostgreSQL

Sie aktivieren die Erweiterung pgvector in PostgreSQL, erstellen eine Tabelle mit einer Vektorspalte, fügen Embeddings ein und führen Abfragen nach nächsten Nachbarn mit dem Kosinus-Distanzoperator aus.

pgvector: Embeddings in PostgreSQL ist eine kostenlose AI Engineering Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Engineering Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Engineering Academy-Kurs umfasst insgesamt 4 Lektionen.

Teile dieser Lektion wurden noch nicht übersetzt und werden auf Englisch angezeigt.

pgvector: Vector Search in PostgreSQL

pgvector is an open-source PostgreSQL extension that adds a vector data type and similarity search operators. It lets you store embeddings alongside your regular application data in the same database you already operate, avoiding a separate vector store.

This is ideal for teams that already use PostgreSQL and want to add semantic search without introducing a new infrastructure dependency.

Enabling the pgvector Extension

Install pgvector from the official repository or use a managed PostgreSQL provider that pre-installs it (Supabase, Neon, AWS RDS, Render). Then enable it in your database with a single SQL command — no restart required.

-- Run this once per database to enable the extension
CREATE EXTENSION IF NOT EXISTS vector;

-- Verify it's installed
SELECT extname, extversion
FROM pg_extension
WHERE extname = 'vector';
-- Returns: vector | 0.7.0 (or similar)

Creating a Table with a Vector Column

Add a vector column by specifying vector(n) where n is the embedding dimension. You can combine it with regular PostgreSQL columns for metadata — this lets you filter by user_id, created_at, or any other field using standard SQL WHERE clauses.

CREATE TABLE documents (
    id          BIGSERIAL PRIMARY KEY,
    content     TEXT NOT NULL,
    category    TEXT,
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    embedding   vector(1536)   -- must match your model dimension
);

-- Index on category for fast metadata filtering
CREATE INDEX ON documents (category);

SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'documents';

Inserting Embeddings from Python

Use the psycopg2 or asyncpg driver to insert rows with embeddings. Convert the Python list of floats to a string in the format '[0.1, 0.2, ...]' which pgvector parses correctly. The pgvector Python package provides a register_vector helper to handle this automatically.

import psycopg2
from pgvector.psycopg2 import register_vector
from openai import OpenAI

conn = psycopg2.connect('postgresql://user:pass@localhost/mydb')
register_vector(conn)
cur = conn.cursor()

client = OpenAI()

document = 'pgvector adds vector search to PostgreSQL.'
resp = client.embeddings.create(model='text-embedding-3-small', input=document)
embedding = resp.data[0].embedding

cur.execute(
    'INSERT INTO documents (content, category, embedding) VALUES (%s, %s, %s)',
    (document, 'database', embedding)
)
conn.commit()
print('Inserted document with embedding')

Cosine Similarity with the <=> Operator

pgvector adds three distance operators:

  • <=> — cosine distance (1 - cosine_similarity)
  • <-> — Euclidean (L2) distance
  • <#> — negative inner product (use for dot product similarity)

For text embeddings, use <=> (cosine distance). ORDER BY distance ASC returns the most similar documents first.

-- Find top 5 documents most similar to a query embedding
-- Replace '[0.1, 0.2, ...]' with the actual query vector
SELECT
    id,
    content,
    category,
    1 - (embedding <=> '[0.1, 0.2, 0.3]'::vector) AS cosine_similarity
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, 0.3]'::vector
LIMIT 5;

Combining Vector Search with SQL Filters

One of pgvector's biggest advantages is that you can combine ANN search with standard SQL WHERE clauses. This enables metadata filtering natively without any special syntax — just write SQL.

-- Semantic search filtered to the 'database' category
-- and only recent documents
SELECT
    id,
    content,
    1 - (embedding <=> %s::vector) AS similarity
FROM documents
WHERE
    category = 'database'
    AND created_at > NOW() - INTERVAL '30 days'
ORDER BY embedding <=> %s::vector
LIMIT 5;

-- In Python with psycopg2:
# cur.execute(sql, (query_embedding, query_embedding))

Creating an HNSW Index for Speed

Without an index, pgvector does an exact scan of every row — fine for under 10,000 rows but slow at scale. Create an HNSW index for approximate nearest neighbor search. The m (connections per node) and ef_construction (build-time search width) parameters trade index size and build time for recall accuracy.

-- Create an HNSW index for cosine distance queries
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

-- At query time, control recall vs speed:
SET hnsw.ef_search = 40;  -- higher = better recall, slower

-- Verify the index is being used:
EXPLAIN SELECT * FROM documents
ORDER BY embedding <=> '[0.1]'::vector(1)
LIMIT 5;

IVFFlat Index: Alternative to HNSW

The IVFFlat index type clusters vectors into lists buckets and searches only the nearest probes buckets at query time. It builds faster than HNSW and uses less memory, but has slightly lower recall for the same speed.

Rule of thumb: use IVFFlat when you need faster index builds during frequent re-indexing; use HNSW for stable corpora that need maximum query speed.

-- IVFFlat index: good for large, infrequently updated corpora
-- lists ≈ sqrt(n) where n is the number of vectors
CREATE INDEX ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

-- At query time, probes controls recall vs speed:
SET ivfflat.probes = 10;  -- check 10 of 100 clusters

Full Python Query Example

Here is a complete Python function that takes a user query, embeds it, runs a pgvector similarity search with metadata filtering, and returns the top-k results as a list of dicts.

import psycopg2
from pgvector.psycopg2 import register_vector
from openai import OpenAI

conn = psycopg2.connect('postgresql://user:pass@localhost/mydb')
register_vector(conn)
client = OpenAI()

def semantic_search(query, category=None, top_k=5):
    resp = client.embeddings.create(model='text-embedding-3-small', input=query)
    q_vec = resp.data[0].embedding

    sql = '''
        SELECT content,
               1 - (embedding <=> %s::vector) AS similarity
        FROM documents
        {where}
        ORDER BY embedding <=> %s::vector
        LIMIT %s
    '''
    where = 'WHERE category = %s' if category else ''
    params = [q_vec, q_vec, top_k] if not category else [q_vec, category, q_vec, top_k]
    cur = conn.cursor()
    cur.execute(sql.format(where=where), params)
    return [{'text': r[0], 'score': r[1]} for r in cur.fetchall()]

pgvector vs Pinecone Trade-offs

Comparing pgvector and Pinecone:

  • pgvector: self-hosted, no extra cost, perfect SQL integration, scales to ~5M vectors well, requires DBA knowledge for tuning
  • Pinecone: fully managed, massive scale (billions of vectors), specialized filtering, more expensive, separate service to operate

Choose pgvector when you already run PostgreSQL and your corpus is under a few million documents. Choose Pinecone for massive scale or when avoiding ops burden is worth the cost.

Using pgvector with Supabase

Supabase is a hosted PostgreSQL service with pgvector pre-installed. It provides a Python client (supabase-py) and a REST API for vector queries, making it the easiest way to get a production pgvector setup without managing a database server yourself.

from supabase import create_client
import os

url = os.environ['SUPABASE_URL']
key = os.environ['SUPABASE_SERVICE_KEY']
supabase = create_client(url, key)

# Insert a document with embedding
supabase.table('documents').insert({
    'content': 'Supabase hosts PostgreSQL with pgvector.',
    'embedding': embedding   # list of 1536 floats
}).execute()

# Vector similarity search via RPC (Supabase edge function)
# result = supabase.rpc('match_documents', {'query_embedding': q_vec, 'match_count': 5}).execute()

Quick Check

Test your understanding of AI Engineering concepts from this lesson.

Lesson Recap

In this lesson you learned: pgvector adds a vector column type and cosine/Euclidean distance operators to PostgreSQL, HNSW indexes enable fast approximate nearest neighbor search at scale, and standard SQL WHERE clauses provide metadata filtering without any special syntax. Next up we compare all the major vector store options to help you choose the right one for your project.

Häufig gestellte Fragen

Ist die Lektion „pgvector: Embeddings in PostgreSQL“ kostenlos?

Ja — der vollständige Text von „pgvector: Embeddings in PostgreSQL“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Engineering Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Engineering Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „pgvector: Embeddings in PostgreSQL“?

Sie aktivieren die Erweiterung pgvector in PostgreSQL, erstellen eine Tabelle mit einer Vektorspalte, fügen Embeddings ein und führen Abfragen nach nächsten Nachbarn mit dem Kosinus-Distanzoperator a… Du übst AI Engineering Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um AI Engineering Academy zu starten?

Keine Vorkenntnisse erforderlich. AI Engineering Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „pgvector: Embeddings in PostgreSQL“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser AI Engineering Academy-Lektion Code schreiben und ausführen?

Ja. Jede AI Engineering Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Warum Sie eine Vektordatenbank benötigen
  2. Erste Schritte mit Pinecone
  3. pgvector: Embeddings in PostgreSQL
  4. Vektorspeicher auswählen und benchmarken
← Zurück zu AI Engineering Academy