Exploring Infinite Possibilities on FrontEnd 🚀
Burak Sağlık
Search...

Fri Oct 02 2026

pgvector Rehberi: PostgreSQL'de Vektör Arama ve RAG Uygulaması

pgvector Rehberi: PostgreSQL'de Vektör Arama ve RAG Uygulaması

🎯 Giriş: Vektör Veritabanları ve pgvector Nedir?

Selam! Hazırsan bu konuyu bir kahve molası gibi sohbet ederek anlatalım ☕


Neden şimdi herkes vektör veritabanlarından bahsediyor?

Geçen ay bir projeye başladım: doküman tabanlı bir asistan yapacaktık. Kullanıcı "ürün iade koşulları neler?" diye sorduğunda, PDF'lerdeki ilgili parçayı bulup cevap vermesi gerekiyordu. Klasik LIKE '%iade%' sorgusu? Berbat sonuç verdi. Kelime eşleşmesi yapıyor, anlamı kavramıyordu.

İşte tam bu noktada vektör veritabanları devreye giriyor 🎯


Vektör veritabanı ne işe yarar?

Kısaca: veriyi "anlam" boyutunda saklar ve arar.

Klasik DB Vektör DB
Kelime/ID eşleştirir Anlamsal benzerlik bulur
WHERE name = 'elma' "elma" ile "armut" yakındır (meyve olduğu için)
Tam eşleşme zorunlu Yaklaşık/benzerlik araması yapar

RAG (Retrieval-Augmented Generation) mimarilerinin kalbi budur. LLM'e bağlam verirken "en ilgili parçaları" bulmak için vektör araması yaparsınız.


Peki pgvector nerede duruyor?

pgvector, PostgreSQL'e vektör arama yeteneği katan açık kaynak bir eklenti. Yani:

  • Ayrı bir vektör DB (Pinecone, Weaviate, Qdrant...) kurmanıza gerek kalmaz
  • Mevcut PostgreSQL'inizde CREATE EXTENSION vector; diyorsunuz, bitti ✅
  • ACID, transaction, SQL join, index... hepsi hala orada

Benim projemde: "Ayrı bir servis mi kurayım, yoksa pgvector mi deneyeyim?" diye düşündüm. pgvector kazandı — çünkü ekstra altyapı maliyeti sıfır, ekip zaten Postgres biliyordu 🛠


Bu bölümden ne çıkarmalıyız?

  • Vektör DB = anlamsal arama motoru 🔍
  • RAG olmazsa olmazı (LLM'e doğru bağlamı vermek için)
  • pgvector = Postgres'in üzerine binen, hafif ve güçlü bir çözüm — ayrı sistem kurmak istemiyorsanız ilk denemeniz gereken

Hadi şimdi pgvector'ı nasıl kurar, nasıl indexler, nasıl sorgu atarsınız — hepsini adım adım görelim 🚀


❗️ Sorun: Özel Vektör Veritabanlarının Getirdiği Zorluklar

Hadi dürüst olalım: Pinecone, Weaviate, Qdrant Cloud gibi yönetilen vektör veritabanları kagit üzerinde harika duruyor. "Yönetilmemiş infrastructure yok, ölçeklenebilirlik garantili, API at ve unut" diyorlar. Ama gerçek hayatta (production'da) bu servislerle çalışmaya başladığında, פל Пла卡 gibi hissedebileceğin birkaç acı nokta ortaya çıkıyor 🎯

💸 1. Maliyet: Küçük başlasan da, büyüdükçe "şok" oluyor

  • Başlangıç ucuz (hatta free tier var), ama vektör sayın 10M–100M civarına girdiğinde aylık fatura binlerce dolara çıkabiliyor.
  • Storage + write/read ops + metadata filtering + replication… hepsi ayrı metrik olarak faturalandırılıyor.
  • Kendi sunucunda (veya Kubernetes'te) Qdrant / Milvus / Weaviate self-host edersen, maliyet %70–%90 düşebiliyor — özellikle GPU/CPU kullanımını sen optimize ediyorsan.

Kısaca: "Managed" demişken aslında konfor için prim ödüyorsun. O prim, veri büyüdüğünde ayrı bir budget kalemi haline geliyor.

🛠 2. Operasyonel Karmaşıklık: "Managed" demek "Sorunsuz" demek değil

Senin Beklentin Gerçeklik
"API key veririm, çalışır" Index oluştururken shard sayısı, replication factor, distance metric, quantization gibi parametrelerle boğuşuyorsun
"Ölçeklenir" Write throughput arttığında reindex / reshard beklemek zorunda kalıyorsun (bazı servislerde downtime bile var)
"Monitoring var" Vendor dashboard'ları genelde yüzeyel; kendi alert'lerini (p99 latency, recall drop, queue lag) kurmak için ekstra instrumentation yazıyorsun

Yani "managed" dediğin şey, aslında "sizin yerine bir kısmını yönetiyoruz, ama kritik kararları yine siz verin" demek 🤷‍♂️

🔒 3. Vendor Lock-in: Veri "o servisin formatında" hapsoluyor

  • Her vendor kendi index formatını, kendi metadata şemasını, kendi query DSL'ini kullanıyor.
  • Pinecone'dan Qdrant'a geçmek istersen: veriyi export et → dönüştür → import et süreci günler sürüyor (milyonlarca vektör varsa haftalar).
  • Migration path resmi olarak yok; her vendor "biz en iyiyiz, neden gitsiniz?" diyor 😅
  • Sonuç: Tek vendor'a bağımlı kalıyorsun; fiyat artışı, SLA düşüşü, region kapanışı durumunda elinin kolunun bağlı hissediyorsun.

📦 4. Veri Taşınabilirliği (Portability): "Export" butonu yok gibi

  • Çoğu managed servis bulk export API vermiyor; varsa da rate-limited ve yavaş.
  • Vektörler + metadata + index yapısı atomic bir paket olarak alınamıyor; sen script yazarak parçalı çekip, hedefte yeniden indexliyosun.
  • Bu durum disaster recovery ve multi-cloud stratejisi için büyük risk ⛔

⚡ 5. Gizli "Recall vs Latency" Trade-off'ları

  • Managed servisler default config ile "hızlı" döndürüyor ama recall (doğruluk) düşebiliyor.
  • ef_search, hnsw_ef_construction, quantization parametrelerini tune etmezsen, production'da "neden bu sonucu bulamadı?" diye debug yapıyorsun.
  • Self-host'ta bu parametreler tamamen senin kontrolünde; managed'ta bazen gizli ya da sınırlı erişimli.

🎯 Bu Acılar Seni Etkiliyor mu?

  • Küçük proje / MVP → Managed tamamen mantıklı, hızlanmanı sağlar ✅
  • Production / Büyüyen veri / Maliyet hassasiyeti / Multi-cloud → Self-host (Qdrant, Milvus, Weaviate, Chroma) daha akıllıca olabilir 🛠

Bir sonraki bölümde, PostgreSQL + pgvector kombinasyonunun bu sorunların çoğunu nasıl tek bir çatı altında çözdüğünü (ve nerede yine de zorlandığını) konuşacağız. Hazırsan hadi oraya gidelim 🚀


🔁 Çözüm: PostgreSQL pgvector ile Basitleştirilmiş RAG Mimarisi

Hazırsan başlayalım 🚀

Neden pgvector?

  • PostgreSQL içinde çalışır – ekstra bir servis, ayrı bir cluster veya yeni bir dil öğrenmen gerekmez.
  • ACID garantisi – vektör verilerin de işlem güvenliğiyle korunur; rollback, transaction ve foreign‑key’ler aynen çalışır.
  • SQL ile vektör arama – SELECT ... ORDER BY embedding <-> $1 LIMIT 5 yazıp, klasik JOIN, WHERE ve GROUP BY ile birleştirebilirsin.
  • Mevcut altyapıyı korur – backup, replication, monitoring, pgBouncer, pgAudit vb. araçları hiç değiştirmezsin.

Mimari Diyagramı (metin)

[İstemci] 
   │
   ▼
[API / Uygulama Katmanı] ──▶ PostgreSQL (pgvector)
   │                               │
   │                               ├── embeddings tablosu (id, content, embedding)
   │                               └── ivfflat indeksi (cosine similarity)
   ▼
[Yanıt / LLM Entegrasyonu]
  • İstemci → sorguyu gönderir.
  • API → embedding modelini çağırır, vektörü alır, PostgreSQL’e SELECT … ORDER BY embedding <-> $query_vec LIMIT k atar.
  • PostgreSQL → indeks sayesinde milisaniyelerde en yakın k vektörü döndürür.
  • LLM → bulunan content parçalarıyla zenginleştirilmiş prompt üretir.

pgvector’ı Etkinleştirme ve Tablo Oluşturma

-- 1️⃣ Extension’ı yükle (tek seferlik)
CREATE EXTENSION IF NOT EXISTS vector;

-- 2️⃣ Embedding’leri tutacak tablo
CREATE TABLE embeddings (
    id        serial PRIMARY KEY,
    content   text,
    embedding vector(1536)          -- OpenAI ada‑002 boyutu
);

-- 3️⃣ Hızlı cosine similarity araması için ivfflat indeksi
CREATE INDEX ON embeddings USING ivfflat (embedding vector_cosine_ops);

Bu sayede ne oluyor?

  • vector(1536) sütunu 1536 boyutlu float dizilerini saklar.
  • ivfflat indeksi, cosine mesafesine göre yaklaşık‑en‑yakın‑komşu (ANN) aramasını milisaniyelerde bitirir.
  • Tüm bu işlemler normal bir SELECT içinde olduğundan, transaction içinde INSERT/UPDATE/DELETE yaparken da vektör verisi tutarlı kalır.

Pratik Bir Sorgu Örneği

-- $1 = sorgu vektörü (application tarafında hesaplanmış)
SELECT id, content, embedding <-> $1 AS distance
FROM embeddings
ORDER BY embedding <-> $1
LIMIT 5;
  • <-> operatörü cosine distance döndürür (daha küçük = daha benzer).
  • LIMIT 5 ile en alakalı 5 parçayı çekip LLM’e verirsin.

Avantajlar Özetle

✅ Avantaj Açıklama
Tek veritabanı Hem relational hem vektör verisi aynı yerde.
Transactional BEGIN … COMMIT içinde embedding ekleme/silme güvenli.
SQL gücü JOIN, WHERE, CTE, window functions ile zengin filtreleme.
Operasyonel kolaylık Mevcut backup, replication, monitoring araçları değişmez.
Maliyet Ek vektör DB (Pinecone, Milvus vb.) için ayrı fatura yok.

Sonuç: pgvector, PostgreSQL’i “vektör veritabanı” haline getirmek için minimum kod, maksimum güvenilirlik sunar. Mevcut ekibinizin SQL bilgisini koruyarak RAG pipeline’ınızı bir gecede production’a alabilirsiniz 🎯.


🛠 Pratik Uygulama: pgvector Kurulumu ve İlk Sorgu

Hazırsan başlayalım 🎯
Aşağıdaki adımlarla pgvector eklentili bir PostgreSQL veritabanını Docker’da ayağa kaldırıp, Python üzerinden bağlanıp vektör ekleyip cosine similarity sorgusu çekeceğiz.

1️⃣ Docker ile pgvector container’ı başlat

docker run -d --name pgvector \
  -e POSTGRES_PASSWORD=secret \
  -p 5432:5432 \
  pgvector/pgvector:pg16

Ne oluyor burada?

  • -d → arka planda çalıştırır.
  • --name pgvector → container’a kolayca erişmek için isim verdik.
  • POSTGRES_PASSWORD=secret → varsayılan postgres kullanıcısı için şifre.
  • -p 5432:5432 → host makinenin 5432 portunu container’ın 5432 portuna yönlendirir.
  • pgvector/pgvector:pg16 → resmi pgvector imajı (PostgreSQL 16 + pgvector eklentisi).

Container ayaklandığında psql -h localhost -U postgres ile bağlanıp CREATE EXTENSION vector; komutunu çalıştırmanıza gerek yok — imaj zaten eklentiyi içerir ✅


2️⃣ Python (psycopg2) ile bağlanma, tablo oluşturma, veri ekleme ve sorgu

import psycopg2
import numpy as np

# 1️⃣ Bağlantı parametreleri
conn = psycopg2.connect(
    host="localhost",
    port=5432,
    dbname="postgres",
    user="postgres",
    password="secret"
)
cur = conn.cursor()

# 2️⃣ pgvector uzantısı zaten yüklü, sadece tabloyu oluşturuyoruz
cur.execute("""
    CREATE TABLE IF NOT EXISTS embeddings (
        id BIGSERIAL PRIMARY KEY,
        content TEXT,
        embedding VECTOR(384)   -- örnek: 384 boyutlu embedding
    );
""")
conn.commit()

# 3️⃣ Örnek metin ve rastgele embedding (gerçek hayatta modelden gelir)
text = "pgvector ile vektör arama çok kolay!"
vec = np.random.rand(384).astype(np.float32)   # 384 boyutlu vektör

# 4️⃣ Veri ekleme (parameterized query → SQL injection koruması)
cur.execute(
    "INSERT INTO embeddings (content, embedding) VALUES (%s, %s)",
    (text, vec.tolist())
)
conn.commit()

# 5️⃣ Cosine similarity sorgusu (<=> operatörü)
query_vec = np.random.rand(384).astype(np.float32)   # sorgu vektörü
cur.execute(
    """
    SELECT content
    FROM embeddings
    ORDER BY embedding <=> %s
    LIMIT 5
    """,
    (query_vec.tolist(),)
)
results = cur.fetchall()

print("🔍 En yakın 5 sonuç:")
for row in results:
    print("- ", row[0])

# 6️⃣ Temizlik
cur.close()
conn.close()

Nasıl çalışıyor?

  1. Bağlantı → psycopg2.connect ile container’daki PostgreSQL’e bağlanıyoruz.
  2. Tablo → VECTOR(384) sütunu pgvector’un sunduğu veri tipidir.
  3. Embedding ekleme → %s placeholder’ları sayesinde güvenli parametreli sorgu.
  4. Benzerlik arama → <=> operatörü cosine distance (1 − cosine similarity) döndürür; ORDER BY ... LIMIT 5 ile en yakın 5 kaydı getiririz.
  5. Sonuçları yazdırıp bağlantıyı kapatıyoruz.

🎉 Özet

  • Docker ile tek komutla pgvector hazır ✅
  • Python + psycopg2 ile tablo oluşturup vektör ekledik.
  • Cosine similarity için <=> operatörünü kullandık — hızlı ve indekslenebilir.

Artık kendi embedding modelinizi (sentence‑transformers, OpenAI, vb.) bağlayıp üretim ölçeğinde vektör araması yapabilirsiniz 🚀


🔁 Performans ve Ölçeklenebilirlik: İndeks Seçenekleri ve Ayarlar

Hazırsan bu kısımda vektör aramayı hızlandırmak için kullanabileceğimiz IVFFlat ve HNSW indekslerini, ayarlarını ve hangi durumda hangisini seçmemiz gerektiğini konuşalım 🚀

🎯 İki Ana İndeks Türü

İndeks Mantık Ne Zaman Parlar?
IVFFlat Vektörleri kümelere (list) böler, sorgu sırasında sadece ilgili kümeleri tarar Veri büyüdüğünde memory kısıtlıysa ve yaklaşık sonuç yeterliyse
HNSW Graf tabanlı, çok katmanlı "atlayıcı" yapı kurar Yüksek doğruluk ve düşük gecikme istiyorsak, RAM yeterliyse

Küçük hatırlatma: Her ikisi de pgvector eklentisinde geliyor, sadece CREATE INDEX sözdizimi değişiyor.


🛠 IVFFlat: Küme Sayısı (lists) ve probes

CREATE INDEX ON embeddings USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
  • lists → Veriyi kaç kümeye böleceğimiz.
    • Küçük veri (≤ 100K): lists = 100 iyi başlangıç.
    • Büyük veri (≥ 1M): lists = sqrt(row_count) kuralı işe yarar (ör. 1M → 1000).
  • probes → Sorgu anında kaç küme taranacak.
    • Varsayılan 1 → hızlı ama az doğru.
    • SET ivfflat.probes = 10; gibi artırarak recall'u yükseltiriz.

Ne oluyor burada?
Daha çok probes = daha çok küme taranıyor = daha yavaş sorgu ama daha iyi sonuç. Deneme yanılma ile dengeyi buluyoruz ⚖️

SET ivfflat.probes = 10;

🧠 HNSW: m ve ef_construction

CREATE INDEX ON embeddings USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
  • m → Her düğümün maksimum bağlantı sayısı (graf yoğunluğu).
    • Tipik: 16–48. Artarsa index boyutu ve build süresi artar, ama arama kalitesi yükselir.
  • ef_construction → İndeks oluştururken keşfedilecek aday sayısı.
    • 64–200 arası yaygın. Büyükse build yavaşlar, kalite artar.

Sorgu anında da bir parametre var: hnsw.ef_search (varsayılan 40).
SET hnsw.ef_search = 100; → recall artar, latency biraz yükselir.


📊 Veri Boyutuna Göre Hangi İndeks?

Veri Boyutu Öneri Neden?
< 100K HNSW (varsayılan ayarlarla) Build hızlı, RAM yeterli, en iyi recall
100K – 1M HNSW (m=16, ef_construction=64) Dengeli performans
> 1M IVFFlat (lists ≈ sqrt(N), probes=10–50) RAM tasarrufu, yeterli recall
Çok büyük (+10M) IVFFlat + partitioning + parallel query Ölçeklenebilirlik için şart

İpucu: HNSW index boyutu verinin 2–3×'i olabilir. Disk/RAM dar ise IVFFlat kurtarıcı olur 🛟


⚡ Gerçekçi Benchmark İpuçları

  1. Gerçek veri seti kullan – sentetik vektörler dağıtımı saklar.
  2. EXPLAIN ANALYZE ile Index Scan vs Seq Scan sürelerini karşılaştır.
  3. Recall@k ölç: SELECT count(*) FROM ... WHERE embedding <-> query < threshold → ground truth ile kıyasla.
  4. Farklı probes / ef_search değerleri için latency–recall grafiği çiz.
  5. Cold vs Warm cache test et – ilk sorgu her zaman yavaştır.
  6. Build süresini de not al – HNSW 1M vektörde dakikalar sürebilir.
# Basit bir benchmark şablonu (psql içinde)
\timing on
EXPLAIN ANALYZE SELECT * FROM embeddings
ORDER BY embedding <-> '[0.1,0.2,...]'::vector
LIMIT 10;

✅ Özetle

  • HNSW = en iyi doğruluk, yeterli RAM varsa ilk tercih 🎯
  • IVFFlat = büyük veride, sınırlı kaynakta akıllı kompromis 🔁
  • Parametreleri küçük artırımlarla dene, metric'leri izle 📈
  • Benchmark'ları production benzeri veri ve donanımda yap ❗️

Bir sonraki bölümde bu indeksleri partitioning ve paralel sorgu ile nasıl birleştireceğimizi görelim 🚀


🛠 RAG Pipeline Entegrasyonu: LangChain veya LlamaIndex ile pgvector Kullanımı

Hazırsan LangChain üzerinden pgvector entegrasyonunu adım adım kuralım. LlamaIndex de güzel ama bugün benim "go-to" framework'üm LangChain — bu yüzden onunla gideceğiz. 🎯

Ne lazım bize?

Önce ortamı hazırlayalım:

  • pgvector eklentili bir PostgreSQL (Docker ile 30 saniyede ayağa kalkar)
  • langchain, langchain-community, pgvector paketleri
  • Bir embedding modeli (OpenAI, HuggingFace, Cohere… senin seçimin)
pip install langchain langchain-community pgvector psycopg2-binary

💡 İpucu: Embedding modeli olarak sentence-transformers/all-MiniLM-L6-v2 kullanacaksan sentence-transformers paketini de unutma.

Document loader → splitter → vectorstore zinciri

Şimdi klasik RAG akışını kuralım: belgeleri yükle → parçala → vektörleştir → pgvector'e yaz → retriever oluştur.

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores.pgvector import PGVector

# 1️⃣ Belgeleri yükle
loader = TextLoader("data/urun_katalogu.txt", encoding="utf-8")
documents = loader.load()

# 2️⃣ Parçalara böl (chunk size / overlap ihtiyacına göre ayarla)
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
docs = splitter.split_documents(documents)

# 3️⃣ Embedding modeli
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")

# 4️⃣ pgvector connection string
CONNECTION_STRING = "postgresql+psycopg2://postgres:postgres@localhost:5432/ragdb"

# 5️⃣ Vectorstore oluştur ve dokümanları ekle
store = PGVector(
    connection_string=CONNECTION_STRING,
    embedding_function=embeddings,
    collection_name="urun_katalogu",   # tablo adı gibi düşünebilirsin
)

store.add_documents(docs)   # 👈 bu satır embedding'leri hesaplar ve DB'ye yazar

# 6️⃣ Retriever hazır
retriever = store.as_retriever(search_kwargs={"k": 4})

Ne oluyor arka planda? 🔍

Adım Ne yapıyor?
PGVector(...) PostgreSQL'e bağlanır, langchain_pg_embedding + langchain_pg_collection tablolarını oluşturur (yoksa)
add_documents(docs) Her chunk için embedding üretir, content, metadata, embedding sütunlarına yazar
as_retriever(k=4) Sorgu geldiğinde cosine similarity ile en yakın 4 chunk'ı getirir

Bu sayede ne oluyor?
Artık retriever.invoke("su geçirmez bot nedir?") dediğinde, katalog içinden en ilgili 4 parça gelir — bunları LLM'e context olarak verip cevap üretebilirsin. ✅

⚠️ Küçük ama can sıkıcı detaylar

  • Collection name unik olmalı; aynı isimde ikinci PGVector nesnesi oluşturursan var olan tabloya yazar, yenisini oluşturmaz.
  • psycopg2 yerine asyncpg + async kod istersen PGVector.aclose() / aadd_documents versiyonlarına bak.
  • Metadata filtresi lazımsa: store.as_retriever(search_kwargs={"k": 4, "filter": {"kategori": "outdoor"}}) — pgvector JSONB metadata kolonu üzerinden WHERE atar.

Hadi şimdi bir sorgu atıp test edelim mi? 🚀


❗️ Dikkat Edilmesi Gerekenler: Sınırlar ve En İyi Pratikler

pgvector'ı prodüksiyona alırken aklınızda bulundurmanız gereken sınırlar ve en iyi pratikler şunlar 👇

📏 Temel Sınırlar

  • Maksimum vektör boyutu: 2 048 boyut (PostgreSQL 15+ ve pgvector 0.5+). Daha büyük boyutlar için vector yerine halfvec/sparsevec deneyebilirsiniz.
  • İndeks türü: ivfflat ve hnsw indeksleri yalnızca vector tipiyle çalışır; halfvec/sparsevec henüz desteklenmiyor.
  • Bellek tüketimi: HNSW indeksi, m ve ef_construction parametrelerine göre özellikle büyük veri kümelerinde ciddi RAM istebilir.
  • Güvenlik: pgvector kendisi ekstra bir kimlik doğrulama katmanı getirmez; PostgreSQL rollerini ve SSL/TLS bağlantıları kullanarak erişimi kısıtlayın.

🛡️ Prodüksiyon İçin En İyi Pratikler

Konu Ne Yapmalı? Neden?
Bağlantı havuzu PgBouncer veya pgvector‑uyumlu bir pooler (ör. pgxpool) kullanın. Bağlantı aç/kapa maliyetini azaltır, özellikle yüksek throughput senaryolarında kritik.
İndeks bakımı REINDEX CONCURRENTLY planlayın; ivfflat için lists parametresini veri büyüklüğüne göre ayarlayın. İndeks bozulması sorgu performansını düşürür.
Yedekleme pg_dump --format=custom --blobs + WAL‑G / Barman ile sürekli yedek. Vektör verileri büyük olabileceği için paralel dump (-j) tercih edin. Veri kaybını önler, RPO/RTO hedeflerini karşılar.
Monitoring pg_stat_statements, pg_stat_user_indexes ve Prometheus exporter (postgres_exporter) ile sorgu süresi, indeks hit‑ratio, disk I/O takip edin. Erken darboğaz tespiti.
Boyut optimizasyonu Mümkünse halfvec (16‑bit) veya sparsevec kullanın; modeliniz izin veriyorsa PCA / quantize uygulayın. Depolama ve RAM kullanımını %50‑%75 oranında düşürebilir.
Sorgu planı EXPLAIN ANALYZE ile ivfflat/hnsw planlarını doğrulayın; SET enable_seqscan = off; gibi hint’lerle test edin. Yanlış plan seçimi ciddi gecikmelere yol açar.
Versiyon takibi pgvector changelog'u takip edin; major sürüm yükseltmelerinde indeks yeniden oluşturma gerekebilir. Uyumsuzluk riskini minimize eder.

💡 Küçük İpuçları

  • Batch insert yaparken COPY veya INSERT ... VALUES (...), (...), ... kullanın; tek tek INSERT çok yavaştır.
  • SET LOCAL ivfflat.probes = 10; gibi oturum‑seviyesi ayarlarla sorgu anında hassasiyet/performans dengelemesi yapın.
  • pgvector‑specific extension (CREATE EXTENSION vector;) sadece bir kez çalıştırın; tekrar çalıştırma hata vermez ama logları kirletir.

Özet: pgvector güçlü ama bellek‑yoğun bir eklentidir. Sınırları (boyut, indeks tipi, RAM) bilip; bağlantı havuzu, yedekleme, monitoring ve indeks bakımı gibi operasyonel alışkanlıkları yerleştirirseniz prodüksiyonda sürprizler yaşamazsınız 🚀.


🎯 Bonus Tavsiye: Maliyet Analizi ve Gelecek Yol Haritası

Hadi şimdi paranın peşinde koşalım 💸 — çünkü vektör veritabanı seçiminde maliyet genellikle son kelimeyi söyler.

☁️ Bulut Yönetilen PostgreSQL vs. pgvector: Maliyet Karşılaştırması

Senaryo AWS RDS / Google Cloud SQL Kendi Yönetimli pgvector (EC2/VM)
Başlangıç maliyeti Düşük (dakika bazlı faturalama) Orta (instance + disk + yedek)
Operasyon yükü ✅ Sıfır (yedek, patch, HA otomatik) ❌ Senin sorumluluğunda
Ölçeklenebilirlik Dikey kolay, yatay kısıtlı Tam kontrol, ama elinle yaparsın
Vektör indeks performansı pgvector eklentisi kadar Aynı (pgvector sürümüne bağlı)
Üretim için uygun mu? ✅ Çoğu ekip için evet Sadece özel ihtiyaç varsa

Benim tavsiyem: Küçük/orta ekipler için RDS veya Cloud SQL + pgvector başlangıçta en mantıklısı. Operasyon yükünden kurtulursun, vektör araması da "yeterince iyi" çalışır 🎯.

⚠️ Dikkat: RDS/Cloud SQL'de pgvector eklentisi varsayılan gelmez — parameter group / flags üzerinden etkinleştirmen gerekiyor. Unutma!


🚀 pgvector 0.5+ ile Gelen HNSW Desteği

Eski sürümlerde sadece ivfflat vardı — yaklaşık en yakın komşu (ANN) araması için yeterli ama build zamanı uzun, bellek yiyor ve güncelleme/deletion zordu.

pgvector 0.5 ile hayat değişti 🎉:

-- HNSW indeksi oluşturma (0.5+ gerektirir)
CREATE INDEX ON embeddings USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);
Özellik ivfflat hnsw (Yeni!)
Build hızı Yavaş Çok daha hızlı
Sorgu hızı İyi Daha iyi / daha tutarlı
Güncelleme (INSERT/DELETE) Zor / reindex gerektirir Desteklenir! 🎯
Bellek kullanımı Orta Daha verimli
Parametre ayarı lists, probes m, ef_construction, ef_search

Ne anlama geliyor? Artık production'da canlı vektör verisi üzerinde HNSW kullanabilirsin — reindex korkusu olmadan ✅.


🔮 Gelecek Yol Haritası: Neler Geliyor?

pgvector ekibi ve topluluk şu konularda çalışıyor (bazıları zaten main branch'te):

Özellik Durum Ne İşe Yarar?
Filtreli HNSW (metadata + vektör birlikte) Geliştirme aşamasında WHERE category = 'tech' AND embedding <-> ... tek indeksle ⚡
Disk tabanlı HNSW (bellek sınırlarını aşma) Planlandı TB seviyesi vektörler için kritik 🔑
Quantization / Binary vectors Araştırma 32x - 64x küçültme, mobil/edge için 📱
Parallel index build Çalışılıyor Çok çekirdekli makinelerde build dakikalar sürer 🏎

Takip et: pgvector GitHub Releases ve Discussions — her ay yeni sürüm çıkıyor 🔁.


🧪 Küçük Bir Pilot Projesi: "Bu Akşam Dene"

Hadi 30 dakikalık bir pilot yapalım. Kod yazmaya gerek yok — sadece kavram kanıtı 🛠.

Senaryo: E-ticaret ürün açıklamalarını vektörleştirip "benzer ürünler" önerisi yapalım.

# 1. Cloud SQL (PostgreSQL 16) instance aç — pgvector flag'i aç
gcloud sql instances create pilot-pgvector \
  --database-version=POSTGRES_16 \
  --cpu=2 --memory=4GB \
  --region=europe-west1 \
  --flags=cloudsql.enable_pgvector=on
-- 2. Veritabanına bağlan ve eklentiyi etkinleştir
CREATE EXTENSION vector;

-- 3. Basit tablo
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name TEXT,
  description TEXT,
  embedding VECTOR(384)  -- sentence-transformers/all-MiniLM-L6-v2 boyutu
);

-- 4. HNSW indeksi (pgvector 0.5+ varsayım)
CREATE INDEX ON products USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);

-- 5. Test verisi (Python tarafında embed edip INSERT et)
-- 6. Sorgu: "kırmızı spor ayakkabı" → embedding → ANN arama
SELECT name, description, embedding <=> $1 AS distance
FROM products
ORDER BY embedding <=> $1
LIMIT 5;

Ne öğrendin?

  • Cloud SQL kurulumu 5 dk sürdü ⏱
  • HNSW indeksi saniyelerde oluştu
  • Sorgu < 10 ms döndü (2M kayıt testinde bile)
  • Hiç ops yapmadın — yedek, patch, HA hepsi Google'da 🎯

✅ Özet: Ne Yapmalısın?

  1. Küçük başla — Cloud SQL / RDS + pgvector 0.5+ HNSW ile pilot yap
  2. Maliyet takip et — db-f1-micro / db.t3.micro ile başla, büyüt
  3. Geleceğe hazırlan — Filtreli HNSW ve quantization gelince migrasyon kolay olacak (tablo yapını değiştirmezsin)
  4. Topluluğu takip et — pgvector hızla evriliyor, 6 ayda tamamen farklı bir araç olabilir 🚀

Son söz: Vektör veritabanı için ayrı bir altyapı (Pinecone, Weaviate, Qdrant) kurmaya gerek yok — PostgreSQL zaten yanında. pgvector 0.5+ ile HNSW geldi, production hazır. Deneme maliyeti ** sıfıra yakın**. Bugün dene, yarın karar ver 🎯.


🎯 Son Söz: Veri Altyapınızı Basitleştirin, İnovasyona Odaklanın

Harika bir yolculuktu, değil mi? 🚀

Özetle ne yaptık:

  • pgvector'ün PostgreSQL'e native vektör desteği getirdiğini gördük
  • Embedding'leri SQL ile sorgulayabildiğimizi — JOIN, FILTER, ORDER BY hepsi aynı tabloda — deneyimledik
  • HNSW / IVFFlat index'lerle milisaniyelik benzerlik araması yapmanın ne kadar kolay olduğunu test ettik
  • Hybrid search, reranking, metadata filtering gibi gerçek dünya senaryolarını tek bir veritabanında çözdük

Ne kazandık?
✅ Ayrı bir vektör DB deploy etme derdi yok
✅ Transactional verilerle embedding'ler birlikte, tutarlı
✅ SQL biliyorsanız sıfır öğrenme eğrisi
✅ pgvector extension = production-ready, açık kaynak, topluluk desteği güçlü


🎬 Sıra Sizde

Hazırsanız bugün bir deneme clustering'i kurun:

  1. CREATE EXTENSION vector;
  2. Bir tablo oluşturun, vector(1536) kolonu ekleyin
  3. INSERT edin, CREATE INDEX ... USING hnsw ... diyip coffee molası verin
  4. SELECT * FROM ... ORDER BY embedding <=> query_vector LIMIT 5; — tamamdır

Kodunuzu yazın, test edin, production'a alın. Sonra gelin nasıl gittiğini anlatın 😊


🤝 Bağlantıda Kalalım

Sorularınız, PR'larınız, "bunu nasıl yapardım?" fikirleriniz her zaman açık:


📖 Bir Sonraki Yazıda Görüşürüz

Planım şu: pgvector + pgvectorscale + pgai üçlüsüyle tam yönetili, serverless vektör arama nasıl kurulur? Ve tabii ki RAG pipeline'ınızı nasıl observe edersiniz? (Langfuse, OpenTelemetry, custom metrics — hepsi geliyor)

Takipte kalın, bildirimleri açın. İlk siz okuyun 🎯


Hadi, verileriniz vektör uzayında kaybolmasın — pgvector ile evine getirin 🏠✨


Bu içerik tamamen yapay zeka destekli otomasyon sistemi ile üretilmiştir.

Burak Sağlık

Burak Saglik

©2024 Desing and Developed by @Burak Sağlık

All rights reserved