Vector Database Selection: Pinecone, Qdrant, Weaviate, pgvector a Confronto
Scegliere il vector database sbagliato per il tuo sistema RAG puo costare settimane di refactoring e budget non pianificato. Nel 2026 il mercato si e consolidato intorno a quattro opzioni principali, ognuna con un profilo di trade-off molto diverso: Pinecone per chi vuole managed service senza ops, Qdrant per chi prioritizza performance e self-hosting, Weaviate per chi ha bisogno di hybrid search nativo, e pgvector per chi vuole rimanere nel proprio database PostgreSQL esistente.
Questa guida ti fornisce i dati di benchmark, i costi reali e i criteri di selezione per prendere una decisione informata basata sul tuo carico di lavoro specifico.
Cosa Imparerai
- Benchmark di latenza e throughput per i principali vector database 2026
- Costi reali a diverse scale (100K, 1M, 10M, 100M vettori)
- Decision matrix: quale database per quale caso d'uso
- Setup pratico con Python per Qdrant e pgvector
- Indici HNSW: parametri critici per performance ottimale
- Quando Milvus e la scelta giusta per 100M+ vettori
Perche il Vector Database Conta Piu del Modello
In un sistema RAG, la qualita della risposta finale dipende per il 60-70% dalla qualita del retrieval, non dal LLM scelto. Un GPT-4o con retrieval scadente produrra risposte peggiori di un GPT-4o-mini con retrieval eccellente. Il vector database e il cuore del retrieval: la sua latenza, la sua precisione e la sua scalabilita determinano la user experience del tuo sistema.
Benchmark 2026: Dati Reali su Hardware Standardizzato
I benchmark seguenti sono stati misurati su un dataset di 1 milione di vettori da 1536 dimensioni (embedding OpenAI text-embedding-3-small), con query k=10, su un server con 8 vCPU e 32GB RAM.
Database | P50 Latency | P99 Latency | Throughput | Recall@10
-----------------|-------------|-------------|-------------|----------
Qdrant (HNSW) | 12ms | 28ms | 850 q/s | 0.989
Pinecone (cloud) | 18ms | 35ms | 600 q/s | 0.987
Weaviate (HNSW) | 22ms | 50ms | 500 q/s | 0.985
pgvector (IVFFlat)| 45ms | 120ms | 200 q/s | 0.941
pgvector (HNSW) | 18ms | 45ms | 420 q/s | 0.983
Milvus (HNSW) | 8ms | 18ms | 1200 q/s | 0.991
Note: pgvector HNSW disponibile da PG 16 (2023), molto migliorato
Qdrant emerge come il leader nel rapporto performance/self-hosting. Pinecone offre SLA garantiti come managed service. pgvector con HNSW (introdotto in PostgreSQL 16) ha colmato quasi completamente il gap con le soluzioni dedicate.
Analisi di Costo a Diverse Scale
Costo mensile stimato (USD) - 1M vettori 1536 dim, 100K query/giorno
Pinecone Starter Pod: ~$70/mese (serverless, pay-per-use)
Pinecone Standard Pod: ~$280/mese (1x p1.x1 pod, SLA garantito)
Qdrant Cloud: ~$85/mese (0.5 vCPU, 1GB RAM managed)
Qdrant Self-hosted: ~$30/mese (infrastruttura cloud VPS)
Weaviate Cloud: ~$95/mese
pgvector (in Postgres): $0 aggiuntivo (gia paghi il DB)
A 10M vettori:
Pinecone: ~$700-1400/mese
Qdrant: ~$250/mese (self-hosted con server dedicato)
pgvector: ~$50/mese aggiuntivo (RAM extra per PostgreSQL)
Milvus: ~$180/mese (self-hosted, ottimo TCO a questa scala)
A 100M+ vettori:
Pinecone: >$5000/mese
Qdrant: ~$800/mese (cluster dedicato)
Milvus: ~$500/mese (cluster distribuito on-premise)
Setup Pratico: Qdrant
Qdrant e la scelta piu comune per team tecnici che vogliono il massimo delle performance con il controllo sul deployment. Ecco il setup completo:
# Qdrant: setup, indexing e querying
from qdrant_client import QdrantClient
from qdrant_client.models import (
Distance, VectorParams, HnswConfigDiff,
PointStruct, Filter, FieldCondition, MatchValue
)
from openai import OpenAI
import uuid
# Connessione (locale o cloud)
client = QdrantClient(url="http://localhost:6333")
# Per Qdrant Cloud: QdrantClient(url="...", api_key="...")
# Crea la collection con HNSW ottimizzato
client.create_collection(
collection_name="knowledge_base",
vectors_config=VectorParams(
size=1536, # dimensione embedding OpenAI
distance=Distance.COSINE
),
hnsw_config=HnswConfigDiff(
m=16, # connessioni per nodo (default: 16)
ef_construct=200, # qualita indice durante build (default: 100)
# Aumentare ef_construct migliora recall ma rallenta l'indicizzazione
),
on_disk_payload=True # payload su disco per risparmiare RAM
)
# Indicizza documenti
openai_client = OpenAI()
def embed_text(text: str) -> list[float]:
response = openai_client.embeddings.create(
input=text,
model="text-embedding-3-small"
)
return response.data[0].embedding
def index_documents(documents: list[dict]) -> None:
points = []
for doc in documents:
embedding = embed_text(doc["content"])
points.append(PointStruct(
id=str(uuid.uuid4()),
vector=embedding,
payload={
"content": doc["content"],
"source": doc["source"],
"category": doc["category"],
"created_at": doc["created_at"]
}
))
# Batch upload per efficienza
client.upsert(
collection_name="knowledge_base",
points=points,
wait=True
)
# Query con filtri
def search(
query: str,
category_filter: str | None = None,
limit: int = 5
) -> list[dict]:
query_embedding = embed_text(query)
query_filter = None
if category_filter:
query_filter = Filter(
must=[
FieldCondition(
key="category",
match=MatchValue(value=category_filter)
)
]
)
results = client.query_points(
collection_name="knowledge_base",
query=query_embedding,
query_filter=query_filter,
limit=limit,
with_payload=True
)
return [
{"content": r.payload["content"], "score": r.score, "source": r.payload["source"]}
for r in results.points
]
# Esempio d'uso
docs = [
{"content": "Come configurare l'autenticazione 2FA...", "source": "docs/security.md",
"category": "security", "created_at": "2026-01-15"},
]
index_documents(docs)
results = search("configurazione sicurezza account", category_filter="security")
Setup Pratico: pgvector
pgvector e la scelta intelligente quando gia usi PostgreSQL: zero infrastruttura aggiuntiva, transazioni ACID, JOIN con altre tabelle. Con HNSW la performance e paragonabile alle soluzioni dedicate per scale sotto 5M vettori.
# pgvector: schema e querying con psycopg2
import psycopg2
from pgvector.psycopg2 import register_vector
import numpy as np
conn = psycopg2.connect("postgresql://user:pass@localhost/dbname")
register_vector(conn)
with conn.cursor() as cur:
# Abilita l'estensione (una tantum)
cur.execute("CREATE EXTENSION IF NOT EXISTS vector")
# Crea la tabella con embedding
cur.execute("""
CREATE TABLE IF NOT EXISTS documents (
id BIGSERIAL PRIMARY KEY,
content TEXT NOT NULL,
source VARCHAR(500),
category VARCHAR(100),
embedding vector(1536), -- dimensione OpenAI
created_at TIMESTAMP DEFAULT NOW()
)
""")
# Crea indice HNSW (migliore performance di IVFFlat)
cur.execute("""
CREATE INDEX IF NOT EXISTS documents_embedding_hnsw_idx
ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200)
""")
conn.commit()
# Inserimento
def insert_document(content: str, source: str, category: str, embedding: list[float]):
with conn.cursor() as cur:
cur.execute(
"INSERT INTO documents (content, source, category, embedding) VALUES (%s, %s, %s, %s)",
(content, source, category, np.array(embedding))
)
conn.commit()
# Query similarity search con filtro
def search_documents(query_embedding: list[float], category: str = None, limit: int = 5):
with conn.cursor() as cur:
if category:
cur.execute("""
SELECT content, source, 1 - (embedding <=> %s) AS similarity
FROM documents
WHERE category = %s
ORDER BY embedding <=> %s
LIMIT %s
""", (np.array(query_embedding), category, np.array(query_embedding), limit))
else:
cur.execute("""
SELECT content, source, 1 - (embedding <=> %s) AS similarity
FROM documents
ORDER BY embedding <=> %s
LIMIT %s
""", (np.array(query_embedding), np.array(query_embedding), limit))
return cur.fetchall()
# Restituisce: [(content, source, similarity_score), ...]
Decision Matrix: Quale Scegliere
Caso d'uso | Raccomandazione | Motivo
------------------------------------|------------------------|----------------------------------
Gia uso PostgreSQL, <1M vettori | pgvector | Zero infra, JOIN nativi, ACID
Startup, MVP rapido | Pinecone Serverless | Zero ops, pay-per-use
Team tecnico, >1M vettori | Qdrant self-hosted | Best performance/cost
Hybrid search nativo necessario | Weaviate | BM25+vector integrato
>100M vettori, cluster distribuito | Milvus | Scalabilita orizzontale
Compliance (dati on-premise) | Qdrant/Milvus | Full control, nessun cloud
Errori Comuni nella Selezione
- Scegliere pgvector con IVFFlat su dataset > 500K vettori: la latenza degrada significativamente. Usa HNSW (disponibile da PostgreSQL 16) o migra a una soluzione dedicata
- Sovrastimare la dimensione degli embedding: text-embedding-3-small a 1536 dimensioni ha performance quasi identica a text-embedding-3-large a 3072 dimensioni ma costa meta e usa meta RAM
- Ignorare ef_search a query time: aumentare ef_search da 100 a 200 in Qdrant/Weaviate migliora il recall dal 95% al 99% con solo 1.3x overhead di latenza
- Dimensionare solo per il volume iniziale: piano la migrazione prima di raggiungere il limite della tua scelta attuale
Parametri HNSW Critici
L'indice HNSW (Hierarchical Navigable Small World) e il cuore della performance nei vector database. Capire i suoi parametri ti permette di ottimizzare il trade-off recall/latency:
Parametro | Effetto sull'indice | Effetto sulla query
----------------|----------------------|--------------------
m (16-64) | Connessioni per nodo | Recall (piu alto = meglio)
| piu alto = piu RAM | Latency (marginale impatto)
| piu alto = build piu |
| lento |
| |
ef_construction | Qualita build | Nessun effetto diretto
(100-500) | piu alto = recall | (determina qualita indice)
| migliore |
| piu alto = build piu |
| lento |
| |
ef_search | Nessun effetto | Recall (molto impatto)
(50-500) | sull'indice | Latency (tradeoff principale)
Configurazione raccomandata per produzione:
- m = 16 (bilanciato), m = 32 (alta accuratezza, +50% RAM)
- ef_construct = 200 (build lenta, alta qualita indice)
- ef_search = 100-200 (aumenta a query time senza ricostruire)
Conclusioni
La regola pratica del 2026: sotto 1M vettori, pgvector con HNSW e spesso la scelta giusta se sei gia su PostgreSQL - zero infrastruttura aggiuntiva e performance competitive. Tra 1M e 50M vettori, Qdrant self-hosted offre il miglior rapporto performance/costo. Oltre 100M vettori, Milvus con deployment distribuito e la scelta standard.
Il prossimo articolo approfondisce le architetture RAG - da Naive RAG a Modular RAG - con codice completo e pattern per gestire i casi d'uso piu complessi.

Commenti
Caricamento commenti...
Accedi per commentare