SQL Server 2025: VECTOR_DISTANCE und VECTOR_SEARCH im Vergleich
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt

SQL Server 2025: VECTOR_DISTANCE und VECTOR_SEARCH im Vergleich

Ein reproduzierbarer SQL-Test zeigt, wie sich exakte und approximative Vektorsuche bei Filtern und Laufzeit unterscheiden.

Eine Vektorsuche kann zehn Ergebnisse liefern und trotzdem andere Dokumente finden als eine exakte Berechnung. Für SQL Server 2025 ist die exakte Trefferliste deshalb die bessere Referenz bei der Entscheidung über einen Vektorindex: Eine Laufzeitmessung zeigt weder ausgelassene Nachbarn noch Treffer, die nach einem Sprachfilter fehlen. Ein fester Datenbestand macht diese Unterschiede überprüfbar.

Einen reproduzierbaren Datenbestand aufbauen

Die Tabelle enthält 10.000 Zeilen mit dreidimensionalen vector-Werten. Die Werte entstehen aus der document_id und bleiben damit bei jedem Neuaufbau gleich, ohne einen Embedding-Dienst oder eine externe Datei zu benötigen. Jede vierte Zeile bekommt den Sprachcode de. Das sind genau 2.500 deutsch markierte Zeilen. Beide Suchverfahren sollen höchstens zehn Treffer liefern.

CREATE TABLE dbo.VectorTest (
    document_id int NOT NULL PRIMARY KEY,
    language_code nvarchar(2) NOT NULL,
    embedding vector(3) NOT NULL
);

;WITH numbers AS (
    SELECT 1 AS n
    UNION ALL
    SELECT n + 1 FROM numbers WHERE n < 10000
)
INSERT dbo.VectorTest (document_id, language_code, embedding)
SELECT n,
       CASE WHEN n % 4 = 0 THEN N'de' ELSE N'en' END,
       CAST(CONCAT('[', n % 97 + 1, ',',
                        n % 89 + 1, ',',
                        n % 83 + 1, ']') AS vector(3))
FROM numbers
OPTION (MAXRECURSION 0);

SELECT COUNT(*) AS total_rows,
       SUM(CASE WHEN language_code = N'de' THEN 1 ELSE 0 END) AS de_rows
FROM dbo.VectorTest;

Als Suchvektor dient [12,35,47], als Distanzmaß cosine. Die Modulo-Ausdrücke erzeugen Testdaten, keine fachlich sinnvollen Embeddings. Für spätere Laufzeitvergleiche gehören der SQL Server-Build, die Hardware, die Indexdefinition und der Cache-Zustand ins Testprotokoll. Die exakte Abfrage liefert zunächst die Referenzliste.

Exakte Treffer mit VECTOR_DISTANCE ermitteln

Der Sprachfilter lässt 2.500 Zeilen übrig; für jede davon berechnet VECTOR_DISTANCE die Cosinus-Distanz zum Suchvektor. Einen Vektorindex verwendet diese Abfrage nicht. Bei gleichen Distanzen entscheidet die document_id über die Reihenfolge.

DECLARE @q vector(3) = '[12,35,47]';

SELECT TOP (10)
       document_id,
       language_code,
       VECTOR_DISTANCE('cosine', embedding, @q) AS distance
FROM dbo.VectorTest
WHERE language_code = N'de'
ORDER BY distance ASC, document_id ASC;

Ohne die WHERE-Klausel entsteht eine zweite Referenzliste für alle 10.000 Zeilen. Die gefilterte Liste enthält die nächsten Vektoren unter den deutsch markierten Datensätzen, die ungefilterte Liste die nächsten Vektoren im gesamten Bestand. Beide Referenzen werden für den Vergleich mit der Indexsuche gebraucht.

VECTOR_SEARCH mit einem Vektorindex testen

Für den Vergleich muss der Index wie die exakte Abfrage das Distanzmaß cosine verwenden. Der hier angelegte DiskANN-Index setzt in SQL Server 2025 aktivierte PREVIEW_FEATURES voraus. Die folgenden Befehle gehören in eine separate Testdatenbank.

ALTER DATABASE SCOPED CONFIGURATION SET PREVIEW_FEATURES = ON;

CREATE VECTOR INDEX ix_VectorTest_embedding
ON dbo.VectorTest (embedding)
WITH (METRIC = 'cosine', TYPE = 'DiskANN');

Die Indexsuche verwendet denselben Suchvektor und liefert mit TOP_N = 10 höchstens zehn Kandidaten. Der Join verbindet die gefundenen IDs mit ihren Sprachcodes in dbo.VectorTest. Die Treffer müssen weder in Anzahl noch in Zusammensetzung mit der exakten gefilterten Liste übereinstimmen.

DECLARE @q vector(3) = '[12,35,47]';

SELECT t.document_id, t.language_code, s.distance
FROM VECTOR_SEARCH(
    TABLE = dbo.VectorTest,
    COLUMN = embedding,
    SIMILAR_TO = @q,
    METRIC = 'cosine',
    TOP_N = 10
) AS s
JOIN dbo.VectorTest AS t
    ON t.document_id = s.document_id
WHERE t.language_code = N'de'
ORDER BY s.distance ASC, t.document_id ASC;

Warum nach dem Sprachfilter weniger Treffer bleiben können

Der Sprachfilter steht in der gezeigten Abfrage außerhalb von VECTOR_SEARCH. Ermittelt der Index zuerst zehn Kandidaten, können davon nach dem Filter beispielsweise nur zwei übrig bleiben, obwohl 2.500 Zeilen den Sprachcode de tragen. Die übrigen Daten bleiben vorhanden. Ob und wann der Filter bei deinem Build in die Indexsuche einfließt, lässt sich am tatsächlichen Ausführungsplan untersuchen.

Ein Gegencheck verwendet dieselbe Indexabfrage ohne WHERE-Klausel. Zehn ungefilterte Treffer und weniger als zehn gefilterte Treffer lenken den Blick auf den Filterpfad, belegen aber für sich genommen keine bestimmte Ausführungsreihenfolge. Wie viele exakte Nachbarn fehlen, zeigt erst der Vergleich der IDs.

Trefferüberschneidung und Laufzeit messen

Die Schnittmenge der gefilterten Trefferlisten zeigt, wie viele exakte Top-10-Treffer auch die Indexsuche liefert. Fehlen Zeilen nach dem Sprachfilter, gehört ihre Anzahl neben die Schnittmenge; allein ein Prozentwert würde diesen Unterschied verdecken. Das folgende SQL speichert beide Listen, zählt gemeinsame IDs und gibt die fehlenden exakten Treffer aus.

DECLARE @q vector(3) = '[12,35,47]';

SELECT TOP (10)
       document_id,
       VECTOR_DISTANCE('cosine', embedding, @q) AS distance
INTO #exact_de
FROM dbo.VectorTest
WHERE language_code = N'de'
ORDER BY distance ASC, document_id ASC;

SELECT t.document_id, s.distance
INTO #approx_de
FROM VECTOR_SEARCH(
    TABLE = dbo.VectorTest,
    COLUMN = embedding,
    SIMILAR_TO = @q,
    METRIC = 'cosine',
    TOP_N = 10
) AS s
JOIN dbo.VectorTest AS t
    ON t.document_id = s.document_id
WHERE t.language_code = N'de';

SELECT (SELECT COUNT(*) FROM #exact_de) AS exact_rows,
       (SELECT COUNT(*) FROM #approx_de) AS approx_rows,
       (SELECT COUNT(*)
        FROM #exact_de AS e
        JOIN #approx_de AS a
            ON a.document_id = e.document_id) AS shared_rows;

SELECT e.document_id, e.distance
FROM #exact_de AS e
LEFT JOIN #approx_de AS a
    ON a.document_id = e.document_id
WHERE a.document_id IS NULL
ORDER BY e.distance ASC, e.document_id ASC;

DROP TABLE #approx_de, #exact_de;

Für die ungefilterte Gegenprobe entfallen in beiden Abfragen die Sprachfilter. Gleiche Distanzen am Rand der Top 10 gehören ins Protokoll: Die exakte Abfrage sortiert dort zusätzlich nach ID, während die approximative Suche ihre Kandidaten bereits mit TOP_N begrenzt. Bei gemeinsamen IDs lassen sich anschließend auch die Rangpositionen vergleichen.

MessgrößeEintrag im Testprotokoll
ErgebniszahlZeilen je Abfrage, mit und ohne Sprachfilter
TrefferüberschneidungGemeinsame IDs und fehlende exakte Top-10-Treffer
LaufzeitWiederholte Messungen mit dokumentiertem Cache-Zustand
TestbedingungenSQL Server-Build, Hardware, Zeilenzahl und Indexdefinition

SET STATISTICS TIME ON liefert CPU-Zeit und verstrichene Zeit für die SQL-Ausführung. Eine Messung im aufrufenden Programm erfasst zusätzlich den Weg bis zur Anwendung. Mehrere Läufe pro Variante und eine getrennte Betrachtung des ersten Laufs machen Cache-Effekte erkennbar. Der synthetische Bestand ersetzt keine Messung mit den Vektordimensionen, Filtern und Datenmengen deiner Anwendung. Vor einem Einsatz außerhalb der Testdatenbank zählt außerdem der Funktionsstatus.

Preview-Status und Plattformgrenzen

Vektorindizes und VECTOR_SEARCH haben in SQL Server 2025 Preview-Status. Sie setzen PREVIEW_FEATURES voraus und sind damit keine Grundlage für einen ungeprüften Produktionseinsatz. Der Status kann sich zwischen Builds ändern; die Konfiguration und Funktionsunterstützung müssen deshalb für den eingesetzten Build geprüft werden.

SQL Server 2025 und Azure SQL-Angebote sind bei der Verfügbarkeit von Vektorfunktionen getrennt zu betrachten. Ein erfolgreicher Test auf einer Plattform belegt keine identische Unterstützung auf einer anderen. Auch die Inhalte einer SQL Server 2022-Schulung sagen nichts darüber aus, ob Preview-Funktionen von 2025 behandelt werden. Die Kategorie Microsoft SQL Server 2025 Training führt zu Schulungen für die neuere Version; ob Vektorindizes behandelt werden, muss aus dem jeweiligen Seminarinhalt hervorgehen. Für die technische Entscheidung bleiben die fehlenden IDs der Prüfpunkt.

Fazit: Fehlende Nachbarn zählen

Erst die exakte Trefferliste zeigt, welchen Preis eine kürzere Laufzeit bei der Trefferqualität hat. Der Sprachfilter kann die Ergebniszahl zusätzlich verringern, und der Preview-Status begrenzt den Einsatz unabhängig vom Messergebnis. Speichere als ersten Schritt die gefilterten Top 10 aus VECTOR_DISTANCE und vergleiche ihre IDs mit jedem Indexlauf.