SQL Server 2025 ile Vector Search: T-SQL ile Semantik Arama Nasıl Yapılır?


1. Başlıyoruz

Önceki makalemde SQL Server 2025 kurulumunu ve SSMS 22 yeniliklerini workshop tadında anlatmıştım. Bu makale de aynı seriye bir devam niteliğinde, bu kez çok konuşulan ve ilk kez T-SQL içine giren bir yetenek ile, Vector Search ile devam edeceğiz. Amacım bu özelliği teoride değil, kendi ortamında çalıştırıp sonucu görebileceğin kadar pratik anlatmak.

Makale boyunca kullanacağımız bazı kelimelerin Türkçe karşılıkları sektörde çok yaygın kullanılmadığı için, ben her zamanki gibi en çok kullanılan İngilizce karşılıklarını (embedding, vector, cosine similarity, RAG) tercih edeceğim. Bu makaleyi okuyup, yeni bir test veritabanı ile beraber SSMS 22’yi açarak adım adım denemenizi tavsiye ederim, çünkü bu özelliği kendinizin görmesi çok daha kalıcı olacaktır.

Kimler için bu yazı? SQL Server üzerinde bugüne kadar LIKE, CONTAINS ya da FREETEXT ile metin arayıp istediği sonuçlara bir türlü ulaşamayan herkese. Daha spesifik olarak: bir doküman tablosunda “anlamca benzer” kayıtları çekmek istemiş veya bir chatbot projesinde arka ucu SQL Server ile kurmayı düşünmüş olan geliştiriciler ve DBA’ler için diyelim.

2. Vector Nedir?

En sadesinden anlatmaya çalışayım. Eskiden bir cümleyi aratırken “aynı kelimeler geçsin” diye bakıyorduk. Oysa “araba” ve “otomobil” aynı anlama gelse bile klasik arama için birbirine yabancı iki kelimeydi. Vector search ise bir cümleyi (veya paragrafı, ürünü, soruyu) alıp onu yüzlerce ya da binlerce sayıdan oluşan bir sayılar dizisine dönüştürür. Bu sayılar dizisine embedding veya kısaca vector diyoruz.

Bu sayı dizisinin güzelliği şurada: anlamca yakın olan iki cümle, matematiksel olarak da birbirine yakın vektörlere sahip oluyor. Örneğin “kredi kartı başvurusu nasıl yapılır” ile “kart nereden alabilirim” cümleleri, kelime düzeyinde neredeyse hiç örtüşmüyor, ama embedding uzayında birbirine çok yakınlar. İşte Vector Search’ün yaptığı tek şey bu: iki vektörün ne kadar yakın olduğunu ölçmek.

Şimdiye kadar bu işi yapmak için genelde Pinecone, Weaviate, Qdrant gibi ayrı bir vektör veritabanı kurmanız gerekiyordu. SQL Server 2025 ile, artık bu ikinci sistemi hayatınızdan çıkarıp veriyi olduğu yerde, T-SQL ile arayabiliyorsunuz. Bu DBA’lar açısından önemli bir kazanım, çünkü verinin hem ana kopyası hem de arama indeksi aynı backup/restore, aynı güvenlik, aynı yüksek erişilebilirlik stratejisiyle yönetiliyor.

3. VECTOR Veri Tipi

SQL Server 2025 ile birlikte yepyeni bir veri tipi geldi: VECTOR(n). Buradaki n, vektörün boyutunu yani kaç sayıdan oluştuğunu belirtiyor. Bu boyut, embedding’i üreten modele göre değişiyor. Örnek olarak:

  • Azure OpenAI text-embedding-3-small → 1536 boyut
  • Azure OpenAI text-embedding-3-large → 3072 boyut
  • Azure OpenAI text-embedding-ada-002 → 1536 boyut

Yani önce hangi model ile embedding üreteceğinize karar vermeli, sonra kolonu ona göre boyutlandırmalısınız. Bir kolonun boyutunu sonradan değiştirmek kolay bir iş değil, o yüzden modelinizi baştan doğru seçin.

VECTOR tipinin içinde aslında float32 değerler tutuluyor. Maksimum destekleneceği açıklanan boyut 1998 civarında (RC sürümüne göre değişebilir, bu yüzden gelecekteki CU’larla birlikte kontrol etmenizi tavsiye ederim). NULL değerlere izin veriyor, ancak NULL bir vektörle yapılan benzerlik sorgusu NULL döner — bu yüzden kolonu NOT NULL yapmak çoğu senaryo için daha temiz.

4. İlk Tablomuzu Kuralım

Laboratuvarda bir doküman koleksiyonu senaryosu kuralım. Şirketinizin IT doküman havuzunda toplanmış bir dizi makale olsun diye düşünün. Her kayıt bir dokümanı temsil ediyor ve dokümanın anlamsal imzası olan embedding’i de aynı satırda tutacağız.

-- Test veritabanını oluşturalım
CREATE DATABASE VectorDemo;
GO
USE VectorDemo;
GO
-- Doküman tablosu
CREATE TABLE dbo.Documents
(
DocumentId INT IDENTITY(1,1) PRIMARY KEY,
Title NVARCHAR(300) NOT NULL,
Content NVARCHAR(MAX) NOT NULL,
Embedding VECTOR(1536) NULL, -- text-embedding-3-small için 1536 boyut
CreatedAt DATETIME2(0) NOT NULL DEFAULT SYSUTCDATETIME()
);
GO

Burada dikkat etmenizi istediğim nokta, Embedding kolonunu başlangıçta NULL bıraktığımız. Bunun nedeni şu: SQL Server bir metnin embedding’ini tek başına üretemiyor (RC sürümü için geçerli). Embedding’i dışarıdan bir AI servisinden alıp, sonra bu kolona yazacağız. Yani iş akışı:

  1. INSERT ile doküman satırını oluşturuyoruz (embedding boş).
  2. Uygulama tarafında o satırın Content alanını alıp Azure OpenAI’a gönderiyoruz.
  3. Dönen embedding’i UPDATE ile aynı satıra yazıyoruz.

Bu üçlü akış, ilk kurulumda bir kez adaptasyon istiyor ama aslında gayet temiz. İlerleyen bölümlerde bunu bir procedure içinde toparlayıp daha kullanışlı hale getireceğiz.

5. Azure OpenAI ile Embedding Üretimi

Embedding’i dışarıdan üretmek için Azure OpenAI kullanacağız. Neden Azure? Çünkü Microsoft ekosistemi içinde kalıyor, Enterprise Agreement’larla kolay faturalanıyor ve network izolasyonu (Private Endpoint) açısından SQL Server ile aynı VNet içinde konuşlandırabiliyorsunuz. Bu DBA’lar için önemli çünkü prompt ve embedding datası public internete çıkmadan Azure backbone içinde gidip gelebiliyor.

Azure portalında bir Azure OpenAI kaynağı oluşturduğunuzu ve içinde text-embedding-3-small modelini deploy ettiğinizi varsayıyorum (deployment adı embed-small olsun). Elinizde şunlar olmalı:

Küçük bir PowerShell script ile bir metnin embedding’ini nasıl aldığımızı gösterelim:

$endpoint = "https://<resource-name>.openai.azure.com"
$deployment = "embed-small"
$apiVersion = "2024-10-21"
$apiKey = "<AZURE_OPENAI_KEY>"
$body = @{
input = "SQL Server 2025 ile vektör arama yeteneği geldi."
} | ConvertTo-Json
$uri = "$endpoint/openai/deployments/$deployment/embeddings?api-version=$apiVersion"
$response = Invoke-RestMethod -Method Post -Uri $uri `
-Headers @{ "api-key" = $apiKey } `
-ContentType "application/json" `
-Body $body
# Embedding, 1536 elemanlı bir dizi olarak döner
$vector = $response.data[0].embedding
$vector.Count # 1536

Dönen $vector artık 1536 elemanlı bir sayı dizisi. Şimdi bunu SQL Server’a iki şekilde yazabiliriz.

Yöntem 1 — JSON string olarak yazmak. SQL Server 2025 bir JSON array’i doğrudan VECTOR’a cast edebiliyor:

-- Önce satırı oluşturalım
INSERT INTO dbo.Documents (Title, Content)
VALUES ('SQL Server 2025 Vector',
'SQL Server 2025 ile vektör arama yeteneği geldi.');
DECLARE @id INT = SCOPE_IDENTITY();
-- Uygulamadan gelen embedding'i JSON array olarak geçiriyoruz
DECLARE @embedding NVARCHAR(MAX) = N'[0.0123, -0.0456, 0.0789, ...]'; -- 1536 eleman
UPDATE dbo.Documents
SET Embedding = CAST(@embedding AS VECTOR(1536))
WHERE DocumentId = @id;

Yöntem 2 — Aynı anda insert etmek. Uygulama katmanında embedding’i zaten hazırladıysanız:

INSERT INTO dbo.Documents (Title, Content, Embedding)
VALUES
('Yedekleme Stratejisi',
'Full, differential ve log yedeklerinin birlikte kullanımı...',
CAST(N'[0.0011, -0.0032, ... ]' AS VECTOR(1536)));

Pratikte Yöntem 2 daha yaygın — uygulama katmanı satırı insert ederken embedding’i de hazır gönderir, tek round-trip olur.

6. Benzerlik Sorgusu — İşte Olay Burada

Tablomuzda on-yirmi tane dokümanın olduğunu ve her birinin embedding’ini doldurduğumuzu varsayalım. Şimdi bir kullanıcı geldi ve “veritabanı kurtarma planım nasıl olmalı?” diye sordu. Bu soruyu da önce embedding’e çeviriyoruz (aynı Azure OpenAI çağrısı), sonra tablodaki tüm dokümanların embedding’i ile karşılaştırıyoruz:

DECLARE @queryEmbedding VECTOR(1536) =
CAST(N'[ ... query embedding ... ]' AS VECTOR(1536));
SELECT TOP (5)
DocumentId,
Title,
VECTOR_DISTANCE('cosine', Embedding, @queryEmbedding) AS Distance
FROM dbo.Documents
WHERE Embedding IS NOT NULL
ORDER BY VECTOR_DISTANCE('cosine', Embedding, @queryEmbedding) ASC;

Birkaç şeye dikkat etmenizi isteyeceğim:

  • VECTOR_DISTANCE mesafeyi döndürüyor, benzerliği değil. Yani küçük değer = daha yakın = daha ilgili. Bu yüzden ORDER BY … ASC yazıyoruz.
  • İlk parametre metrik adı: ‘cosine’, ‘euclidean’, ‘dot’. Metin embedding’leri için genelde cosine standarttır.
  • Tüm tabloyu tarıyor gibi görünse de, küçük ve orta veri setlerinde bu performans genelde yeterli. Milyonlarca satıra çıktığınızda index devreye giriyor (bir sonraki bölümün konusu).

Sonuç olarak kullanıcıya geri döndürdüğünüz dokümanlar, kelime üzerinden değil, anlam üzerinden seçilmiş olur. Kullanıcı “kurtarma” dese bile “restore, yedek, felaket kurtarma” geçen dokümanlar da listeye girer.

7. Performans ve Index Notu

Burada çok hızlı bir uyarı bırakmak istiyorum, çünkü bu konu gelecek bölümün ana teması olacak. VECTOR kolonunda yapılan benzerlik araması, varsayılan olarak tüm satırları tarar (brute force) — klasik SQL Server performans optimizasyonu yaklaşımlarımızda pek tercih etmediğimiz türden bir lineer tarama. Bu, 10.000-50.000 satır civarına kadar gayet makul sonuç verir. Ancak milyonlarca satırda bu lineer tarama yavaşlar.

SQL Server 2025’in getirdiği çözüm DiskANN indeksi:

CREATE VECTOR INDEX IX_Documents_Embedding
ON dbo.Documents(Embedding)
WITH (metric = 'cosine');

DiskANN, Microsoft Research’ün geliştirdiği Approximate Nearest Neighbor algoritması. “Approximate” kelimesinin altını çiziyorum — bu index tam doğru sonuç yerine, çok yakın tahmini sonucu çok hızlı döndürür. Çoğu arama senaryosunda zaten insan gözü ilk 10 sonuca bakıyor, oradaki tek satırlık fark önemli değil. Ama örneğin regülasyon veya hukuk gibi kritik senaryolarda brute force tercih edebilirsiniz.

Gelecek bölümde DiskANN indeksini kurup, aynı sorguyu index’li ve index’siz çalıştırarak süre farkını beraber gözleyeceğiz.

8. Sırada Ne Var?

Bu bölümde temel kavramları aldık, tabloyu kurduk, Azure OpenAI ile embedding üretip SQL Server’a yazdık ve ilk benzerlik sorgumuzu çalıştırdık. İkinci bölümde şunları ele alacağız:

  • Daha gerçekçi bir senaryo: bir PDF koleksiyonunu chunk’lara bölüp toplu embedding üretmek
  • DiskANN indeksinin kurulumu, parametreleri ve performans karşılaştırması
  • RAG (Retrieval-Augmented Generation) mimarisi: SQL Server’dan çekilen en ilgili 5 dokümanı bir LLM prompt’una gömerek soru-cevap sistemi kurmak
  • Güvenlik notları: API key’lerin Credential + SECRET ile tutulması, Private Endpoint kullanımı

Okuduğunuz için teşekkür ederim. Kendi test ortamınızda denediğinizde karşılaştığınız sorunları, performans gözlemlerinizi veya merak ettiklerinizi yorumlara yazabilirseniz, ikinci bölümde örneklerle cevaplamaya çalışırım.


Yazar hakkında

Yavuz Filizlibay — Database Solution Architect

SQL Server ekosisteminde uzun yıllardır performans, güvenlik, yüksek erişilebilirlik ve raporlama (SSRS) üzerine çalışıyorum. Dubai’den SQL Server Administration, Querying, SSRS ve Security eğitimleri ile danışmanlık hizmeti veriyorum. Yeni makalelerden haberdar olmak için LinkedIn’de bağlanabilir, eğitim veya danışmanlık için iletişime geçebilirsiniz.


Yavuz Filizlibay sitesinden daha fazla şey keşfedin

Subscribe to get the latest posts sent to your email.


Bir Cevap Yazın

Bu site istenmeyenleri azaltmak için Akismet kullanır. Yorum verilerinizin nasıl işlendiğini öğrenin.

Yavuz Filizlibay sitesinden daha fazla şey keşfedin

Okumaya devam etmek ve tüm arşive erişim kazanmak için hemen abone olun.

Okumaya Devam Edin

Yavuz Filizlibay sitesinden daha fazla şey keşfedin

Okumaya devam etmek ve tüm arşive erişim kazanmak için hemen abone olun.

Okumaya Devam Edin