Mit Oracle 23ai stellt Oracle den Datentyp Vector zur Verfügung.
Der Datentyp speichert Vectoren.
Beim Anlegen kann die Anzahl (Dimenstion) der Vektorwolke, der Datentyp der einzelnen Vektoren und ob es Lücken gibt (DENSE - keine Lücken, SPARSE mit nicht besetzten Vektoren) angeben werde.
VECTOR(number_of_dimensions, dimension_element_format, DENSE)
Als Vector Darstellungen können folgende Datentypen gewählt werden:
Vectors (DENSE oder SPARSE ) werden intern als Securefile BLOBs gespeichert und die standard embedding model vectoren sind zwischen 1.5KB and 12KB groß.
Um den notwendige Speicherplatz abzuschätzen können folgende Formeln hilfreich sein:
Mehr dazu unter ⇒ https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/create-tables-using-vector-data-type.html
Wie aber damit umgehen und für was können wir das einsetzen?
Die vier wichtigen Elemente:
Ein Satz von Vectoren beschriebt die Eigenschaften eines Daten Elementes, Datensatzes, Words oder eine Satzes oder eine Bildes in einer Art Punkt Wolke in n Dimensionen im Raum.
Ich stelle mir so einen Vektor Satz eher wie eine 3-Dimensionale Punktwolke vor, die Oberfläche der Figur sind die Punkte , die Gerade zum Mittelpunkt der Punktwolke ist der jeweilige Vektor.
Also so eine Art Kartoffel mit den verschiedensten Formen.
In den meisten Beispiel reden wir noch 2-3 Dimensionen, In der Praxis haben Vektoren oft mehrere hundert oder sogar tausende Dimensionen (z. B. 2024 Dimensionen). Jede Dimension repräsentiert ein spezifisches Merkmal des Datenelements, das durch KI-Modelle (z. B. Sentence Transformer oder CNNs) gelernt wurde.
Die eigentliche AI findet beim Erstellen des Vektors statt, beim späteren Suchen kann dann mit diversen Vergleichs-Algorithmen in diesen „Wolken“ gesucht werden.
Dazu wird ein Modell für eine Künstliche Intelligenz (KI) (z. B. ein Transformer-Modell wie BERT oder ein Convolutional Neural Network (CNN) für Bilder) zuvor trainiert, um die semantischen oder visuellen Merkmale von Daten (z. B. Texten, Bildern) zu erfassen.
Die Aufgabe teilt sich also in zwei hauptsächliche Aufgaben, ein Daten Element in einen passenden Vektor wandeln und speichern; und dann über eine Suche in dem Vektor Raum die wahrscheinlichsten Ähnlichkeiten zu identifizieren.
Da heißt das Feature Vector Search umfasst die folgenden wichtigen Architektur Elemente, die zu verstehen sind:
Details auch unter https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/vector_distance.html
D.h. wir suchen im Prinzip auf in den Vektor Räumen immer nach Ähnlichkeiten!
Und sortieren das Ergebnis nach dem entsprechenden Ähnlichkeitsmaßes, das für unsere jeweilige Aufgabe die beste Wahrscheinlichkeit darstellt auch wirklich etwas sinnvolles zu finden.
Als Vorbereitung wurde eine 23ai Container Umgebung (siehe ⇒ Oracle Datenbank 23ai Free Edition über ein Container Image unter Linux 9 als Testumgebung für AI Vector Search verwenden ) bereitgestellt und über den Python Client OML4Py (siehe ⇒ Oracle Datenbank 23ai - Modelle für Vector Search über Python OML4Py bereitstellen und mit Hybrid Vector Search testen ) ein Model wie ALL_MINILM_L6_V2 geladen.
Da die Vektorisierung und das Vergleichen von Vektoren zwei komplett unterschiedliche Dinge sind, kann auch ein eigener Vektor Algorithmus erstellt werden.
So soll in diesem kleinen Beispiel nach Auto Farben gesucht werden, Kunden sucht über einen Hex Color Picker eine Farbe, wie f20707 und in der Suche werden alle Fahrzeuge mit einer ähnlichen Farbe angezeigt in dem wir einen Farb Vector definieren aus [ Farbanteil R [0 .. bis 256] , Farbanteil G [0 .. bis 256], Farbanteil R [B .. bis 256], Hersteller [0 - x ], Fahrzeug Typ [ 1 … 10 ] ], Hersteller und Fahrzeug Typ werden nach Ähnlichkeit in der Wertemege dafür sortiert, wie BMW 1, VW 2, Merzedes 3, Citrön 5 , Ferrari 80, Bently 999 usw, Typen wie Stufenheck =1, Kombi 2, Transporter 10, Pickup 20, LKW 99, Kettenbagger 999, um hier wieder Ähnlichkeiten zu identifizieren.
Auch können wir nun bei diese einfachen Vektor Mengen das auch mal mit dem Taschenrechner nachrechnen, um die Vektor Distanzen besser zu verstehen.
Ein Beispiel - Suche nach Automobilen:
DROP TABLE car_search; CREATE TABLE car_search ( id NUMBER(9), color varchar2(6), manufacturerid NUMBER(4), car_type NUMBER(2), search_vector VECTOR(5, FLOAT32 , DENSE) ); -- ein schwarzes Auto -- 1 BMW -- 1 Stufenheck INSERT INTO car_search VALUES ( 1, '000000',1,1,'[0,0,0,1,1]'); -- ein weißes Auto -- 2 VW -- 2 Kombi INSERT INTO car_search VALUES ( 2, 'ffffff',2,2,'[256,256,256,2,2]'); ----- commit; -----
Abfragen:
COLUMN v_L1_DISTANCE format 999G990D0999 heading "Vector Distance|L1 or MANHATTAN" COLUMN v_L2_DISTANCE format 999G990D0999 heading "Vector Distance|L2 or EUCLIDEAN" COLUMN v_COSINE_DISTANCE format 999G990D0999 heading "Vector Distance|COSINE" COLUMN v_INNER_PRODUCT format 999G990D0999 heading "Vector Distance|INNER_PRODUCT" COLUMN v_HAMMING_DISTANCE format 999G990D0999 heading "Vector Distance|HAMMING" COLUMN v_JACCARD_DISTANCE format 999G990D0999 heading "Vector Distance|JACCARD" VARIABLE query_vector CLOB -- ein schwarzes Auto -- 1 BMW -- 1 Stufenheck BEGIN :query_vector := '[0,0,0,1,1]'; END; / SELECT ID , manufacturerid , car_type , vector_distance(search_vector, :query_vector, MANHATTAN) AS v_L1_DISTANCE , vector_distance(search_vector, :query_vector, EUCLIDEAN ) AS v_L2_DISTANCE , vector_distance(search_vector, :query_vector, COSINE ) AS v_COSINE_DISTANCE , vector_distance(search_vector, :query_vector, DOT) AS v_INNER_PRODUCT , vector_distance(search_vector, :query_vector, HAMMING ) AS v_HAMMING_DISTANCE --, vector_distance(text_vector, :query_vector, JACCARD) as v_JACCARD_DISTANCE FROM car_search
Vector Distance Vector Distance Vector Distance Vector Distance Vector Distance ID MANUFACTURERID CAR_TYPE L1 OR MANHATTAN L2 OR EUCLIDEAN COSINE INNER_PRODUCT HAMMING ---------- -------------- ---------- --------------- --------------- --------------- --------------- --------------- => Suchvektor 1 1 1 0.0000 0.0000 0.0000 -2.0000 0.0000 2 2 2 770.0000 443.4073 0.9936 -4.0000 5.0000
Der Sichvektor des Kunden könnten also sein, Farbe f20707, Citrön, Kombi in der Auswahl >= das ergibt dann folgenden Suchvektor ⇒ [ 242, 7, 7 , 5, 2]
BEGIN :query_vector := '[ 242, 7, 7 , 5, 2]'; END; / -- liefert mit obiger Abfrage die folgenden Ergebnisse: Vector Distance Vector Distance Vector Distance Vector Distance Vector Distance ID MANUFACTURERID CAR_TYPE L1 OR MANHATTAN L2 OR EUCLIDEAN COSINE INNER_PRODUCT HAMMING ---------- -------------- ---------- --------------- --------------- --------------- --------------- --------------- 1 1 1 261.0000 242.2375 0.9796 -7.0000 5.0000 2 2 2 515.0000 352.4301 0.3898 -65,550.0000 4.0000
Was muss jetzt dem Kunden angezeigt werden? Was ist am ähnlichsten?
Die Treffermenge wird dann nach dem entsprechenden Distance Algorithmus sortiert, damit das wahrscheinlichste Ergebnis in der Treffermenge ganz oben steht.
Im nächsten Testschritt lässt sich die Tabellen nun einfach über DBMS_RANDOM mit größeren Datenmengen füllen und auch ein passender Index auf der Vector Spalte anlegen.
CREATE SEQUENCE CAR_SEARCH_SEQ; CREATE OR REPLACE PROCEDURE fillColorTab (p_num_records NUMBER) IS v_color varchar2(256); v_r pls_integer; v_g pls_integer; v_b pls_integer; v_vector varchar2(256); v_cnt pls_integer; BEGIN v_cnt:=0; while v_cnt < p_num_records loop v_r:=FLOOR(DBMS_RANDOM.VALUE(0, 256)); v_g:=FLOOR(DBMS_RANDOM.VALUE(0, 256)); v_b:=FLOOR(DBMS_RANDOM.VALUE(0, 256)); v_color:= lpad(TRIM((LOWER(to_char(v_r, 'XX'))) ),2,'0')|| lpad(TRIM(LOWER(to_char(v_g, 'XX'))),2,'0')||lpad(TRIM(LOWER(to_char(v_b, 'XX'))),2,'0'); dbms_output.put_line(v_color); v_vector:='['||v_r||','||v_g||','||v_b||','||1||','||1||']'; INSERT INTO CAR_SEARCH(ID, COLOR, MANUFACTURERID, CAR_TYPE, SEARCH_VECTOR) VALUES ( CAR_SEARCH_SEQ.nextval -- ID , v_color -- COLOR , 1 -- MANUFACTURERID , 1 -- CAR_TYPE , TO_VECTOR ( v_vector ) --SEARCH_VECTOR ); IF MOD(v_cnt,1000) = 0 THEN commit; END IF; v_cnt:=v_cnt+1; END loop; commit; END fillColorTab; / SET serveroutput ON TRUNCATE TABLE CAR_SEARCH; EXEC fillColorTab(100);
Auf dieser Datenmenge können wir nun testen mit welchen Ähnlichkeitsmaß wir die sinnvollste Sortierung erreichen.
Optimiert lässt sich das ganze durch die Umstellung von auf HSV/HSB (Farbton, Sättigung, Wert/Helligkeit) statt RGB-Modell mit den drei unabhängige Kanäle (Rot, Grün, Blau), diese boten sich für diese Demo an.
Mehr dazu unter Oracle Datenbank 23ai - Mit Vectoren in der Oracle Datenbank Daten vergleichen - Demo Applikation für die Suche nach Farben
Viel wird mit dem COSINE_DISTANCE - (Name in der Syntax von Oracle COSINE) gearbeitet
Misst die Ähnlichkeit der Richtungen der Vektoren, nicht deren absoluten Wert.
D.h. folgende Vektoren haben die gleiche Cosinus Distanz:
'[ 0, 0, 0 ]' '[ 125, 125, 125 ]' '[ 256, 256, 256 ]' => 0
In unseren oberen Beispiel dazu wird dann schnell klar, das dieser Ähnlichkeitsmaße für folgende Aufgabe dann ungeeignet ist:
In einer Suche sollen ähnliche Farben über Ihren RGB Wert identifiziert werden:
⇒ Schwarz / Grau / Weiß ist dann vom Ähnlichkeitsmaße die gleiche Farbe
Bei Semantischen Analyse sieht das dann gleich ganz anders aus da hier die Richtung des Vektors in der Punktwolken Menge eines Satzes den entscheidenden Hinweis geben kann.
L2_DISTANCE - (Name in der Syntax von Oracle vector_distance EUCLIDEAN, als einzelne Methode L2_DISTANCE ) - Misst den direkten Abstand zwischen zwei Vektoren im Raum.
select vector_distance('[ 0, 0, 0 ]','[ 125, 125, 125 ]', EUCLIDEAN) from dual; 216.50635094610965 select vector_distance('[ 125, 125, 125 ]','[ 256, 256, 256 ]', EUCLIDEAN) from dual; 226.8986557915229 -- die Short Methode heißt dann wieder L2_DISTANCE! select L2_DISTANCE('[ 0, 0, 0 ]','[ 256, 256, 256 ]') from dual; 443.40500673763256
Rechnen wir das mal nach:
A=[125, 125, 125],B=[256, 256, 256] ⇒ EUCLIDEAN(A,B)≈226.90
⇒ Schwarz / Grau / Weiß ist dann vom Ähnlichkeitsmaße dann mit einem gewissen Abstand, werde das bald möglichst als APEX App bauen um das „graphisch“ anzuzeigen ob das so am Ende gehen könnte, hier geht es ja erstmal um das Prinzip.
Die euklidische Norm (auch bekannt als L²-Norm oder Euclidean Norm) eines Vektors ist ein Maß für die „Länge“ oder den „Abstand“ des Vektors im euklidischen Raum. (also von 0 aus)
Sie wird berechnet als die Quadratwurzel der Summe der quadrierten Komponenten des Vektors.
SELECT VECTOR_NORM(VECTOR('[2, 2]')) AS euclidean_norm ; 2.8284271247461903 SELECT vector_distance(VECTOR('[2, 2]'), VECTOR('[0, 0]'), EUCLIDEAN ); 2.8284271247461903
VECTOR_NORM(VECTOR('[2, 2]')) entspricht als der Distance vom 0 Punkt = vector_distance(VECTOR('[2, 2]'), VECTOR('[0, 0]'), EUCLIDEAN )
SELECT vector_distance(VECTOR('[2, 2]'), VECTOR('[2, 2]'), EUCLIDEAN ); 0.0 -- Abstand der beiden Vectoren im Raum SELECT vector_distance(VECTOR('[1, 1]'), VECTOR('[2, 2]'), EUCLIDEAN ) ; 1.4142135623730951
⇒ https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/vector_norm.html
Das kann zum Beispiel dazu benutzt werden um in den Daten die Vectoren mit starken Abweichungen zu identifizieren.
Im nächsten Schritt wird ein Daten Element über ein KI Modell in einen Vector umgewandelt, dazu steht die Funktion „vector_embedding“ zu Verfügung.
SELECT vector_embedding(ALL_MINILM_L6_V2 USING 'Das ist ein Text' AS DATA) FROM dual;
[-4.86620981E-003,1.44163042E-001,1.31779145E-002 ,6.53347224E-002,1.372308E-002,8.78371745E-002,1.14743046E-001,7.9288438E-002,7.86188394E-002,-6.70713037E-002,-2.15163687E-003,-2.01251972E-002,3.27725452E-003,-3.89427617E-002,-3.76474112E-002 ...... ,-1.39121301E-002,2.33094934E-002,8.33002329E-002,-7.44610419E-003,-7.68417343E-002,-7.87851494E-003,5.6516204E-002,2.01204326E-002,9.20519829E-002,-3.29588093E-002 ]
Besser Lesbar mit „JSON_ARRAY returning clob „ausgeben:
SELECT JSON_ARRAY( vector_embedding(ALL_MINILM_L6_V2 USING 'Das ist ein Text' AS DATA) returning CLOB) AS DatenFormat FROM dual; [[-0.00486621,0.14416304,0.013177915,0.06533472,0.01372308 ,0.087837175,0.11474305,0.07928844,0.07861884,-0.0670713,-0.0021516369,-0.020125197,0.0032772545,-0.03894276 ,-0.03764741,0.007716139,-0.011220228,0.026907498,0.023640944 ,-0.030299427,-0.020495197920648,0.002982179,-0.018670402,-0.00887637,....]]
Das Ergebnis kann wiederum als Datentyp Vector gespeichert werden.
Wie groß ist der Vector geworden?
SELECT VECTOR_DIMENSION_COUNT( vector_embedding(ALL_MINILM_L6_V2 USING 'Das ist ein Text' AS DATA) ) AS Anzahl_Dimensionen FROM dual; ANZAHL_DIMENSIONEN ------------------ 384
Welches Datenformat hat der Vector
SELECT VECTOR_DIMENSION_FORMAT( vector_embedding(ALL_MINILM_L6_V2 USING 'Das ist ein Text' AS DATA) ) AS DatenFormat FROM dual; DATENFORMAT --------------- FLOAT32
Beispiel Tabelle mit einem Vector auf Basis eine Analyse mit einem KI Modell auf die Daten anlegen:
DROP TABLE vtexte; CREATE TABLE vtexte (id NUMBER(8) , text varchar2(4000) , text_vector VECTOR );+ INSERT INTO vtexte VALUES (1,'Ein Hund steht neben der Hütte' , vector_embedding(ALL_MINILM_L6_V2 USING 'Ein Hund steht neben der Hütte' AS DATA) ); INSERT INTO vtexte VALUES (2,'Die liebsten Haustiere sind Katze und Hund',vector_embedding(ALL_MINILM_L6_V2 USING 'Die liebsten Haustiere sind Katze und Hund' AS DATA)); INSERT INTO vtexte VALUES (3,'Die Katze auf dem Dach',vector_embedding(ALL_MINILM_L6_V2 USING 'Die Katze auf dem Dach' AS DATA)); commit;
Ließe sich mit einem Trigger oder ähnlichen auch lösen .-).
Mit den verschienden Vektor Distance Verfahren können wir nun die Ähnlichkeit des gesuchten Begriffes mit dem vorhanden Daten ermitteln.
Dazu verwenden wir die Funktion vector_distance (siehe ⇒ https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/vector_distance.html ) um den Abstand nach den jeweilen Algorithmus zu ermitteln.
Abfrage:
COLUMN v_L1_DISTANCE format 999G990D0999 heading "Vector Distance|L1 or MANHATTAN" COLUMN v_L2_DISTANCE format 999G990D0999 heading "Vector Distance|L2 or EUCLIDEAN" COLUMN v_COSINE_DISTANCE format 999G990D0999 heading "Vector Distance|COSINE" COLUMN v_INNER_PRODUCT format 999G990D0999 heading "Vector Distance|INNER_PRODUCT" COLUMN v_HAMMING_DISTANCE format 999G990D0999 heading "Vector Distance|HAMMING" COLUMN v_JACCARD_DISTANCE format 999G990D0999 heading "Vector Distance|JACCARD" COLUMN ID format 999 heading "ID" COLUMN text format a126 heading "Text" VARIABLE query_string VARCHAR2(1000) VARIABLE query_vector CLOB BEGIN :query_string := 'Die Katze steht auf der Hütte'; SELECT vector_embedding(ALL_MINILM_L6_V2 USING :query_string AS DATA) INTO :query_vector; END; / WITH results AS ( SELECT ID , TEXT , vector_distance(text_vector, :query_vector, MANHATTAN) AS v_L1_DISTANCE , vector_distance(text_vector, :query_vector, EUCLIDEAN ) AS v_L2_DISTANCE , vector_distance(text_vector, :query_vector, COSINE ) AS v_COSINE_DISTANCE , vector_distance(text_vector, :query_vector, DOT) AS v_INNER_PRODUCT , vector_distance(text_vector, :query_vector, HAMMING ) AS v_HAMMING_DISTANCE --, vector_distance(text_vector, :query_vector, JACCARD) as v_JACCARD_DISTANCE FROM vtexte ) SELECT * FROM results ORDER BY 1;
Ergebnis:
Vector Distance Vector Distance Vector Distance Vector Distance Vector Distance ID Text L1 OR MANHATTAN L2 OR EUCLIDEAN COSINE INNER_PRODUCT HAMMING ---- ------------------------------------------------------------------------------------------------------------------------------ --------------- --------------- --------------- --------------- --------------- 1 Ein Hund steht neben der Hütte 10.8571 0.7016 0.2461 -0.7539 381.0000 2 Die liebsten Haustiere sind Katze und Hund 11.8764 0.7725 0.2984 -0.7016 381.0000 3 Die Katze auf dem Dach 10.4859 0.6971 0.2430 -0.7570 381.0000
Auch hier gilt wie bei unsern ersten Beispiel, die Kunst im Einsatz der Vector Search ist es auf den Daten den passenden Ähnlichkeitsmaßstab zu finden um die Daten am sinnvollsten zu sortieren!
Bisher müssen wir mit einem Full Table Scan alle Vectoren mit dem Suchvektor verleichen um eine Sortierung nach Ähnlichkeit zu erreichen.
D.h. von der Performance haben wir ein O(n) Probem, der Rechenaufwand steigt linear mit der Datenmenge und wird schnell sehr unpraktisch.
Um das zu vermeiden verwenden wir Indexe auch auf den Vector Datentyp.
Zwei Typen werden unterstützt:
siehe auch ⇒ https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/create-vector-index.html
IVF (Inverted File) Flat index - partitioned-based index - classifed as Neighbor Partition Vector Index
Ein IVF (Inverted File) Flat Index ist ein Indexierungsverfahren, bei dem der Vektorraum in Cluster (Gruppen ähnlicher Vektoren) unterteilt wird, um die Suche nach den nächsten Nachbarn zu beschleunigen, indem nur die relevanten Cluster durchsucht werden, anstatt den gesamten Vektorraum.
HNSW (Hierarchical Navigable Small Worlds) index -graph-based index - In-Memory Neighbor Graph Vector Index
Effizienter Algorithmus für die annähernde k-Nächste-Nachbarn-Suche (k-NN) in hochdimensionalen Vektorräumen, der durch die Kombination von Hierarchien und Graphen eine schnelle und skalierbare Suche ermöglicht
Die annähernde k-Nächste-Nachbarn-Suche (k-NN) ist ein Algorithmus, der die k ähnlichsten Datenpunkte zu einem gegebenen Query-Punkt in einem Datensatz findet, wobei zugunsten von Geschwindigkeit und Skalierbarkeit eine geringe Genauigkeit in Kauf genommen wird.
Gute Erklärung findet sich auch hier ⇒ Vector Database Search - Hierarchical Navigable Small Worlds (HNSW) Explained ⇒ https://www.youtube.com/watch?v=77QH0Y2PYKg
DROP INDEX idx_vtexte_hnsw_idx ; CREATE VECTOR INDEX idx_vtexte_hnsw_idx ON vtexte (text_vector) ORGANIZATION INMEMORY NEIGHBOR GRAPH DISTANCE COSINE WITH TARGET ACCURACY 90 PARAMETERS (TYPE HNSW, neighbors 40, efconstruction 500);
Index wird verwendet wenn:
Abfrage:
EXPLAIN PLAN FOR SELECT ID , TEXT , vector_distance(text_vector, :query_vector, COSINE ) AS v_COSINE_DISTANCE FROM vtexte ORDER BY vector_distance(text_vector, :query_vector, COSINE ) FETCH APPROX FIRST 3 ROWS ONLY; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT ----------------------------------------------------------- Plan hash VALUE: 3113142583 ------------------------------------------------------------------------------------------------------ | Id | Operation | Name | ROWS | Bytes | Cost (%CPU)| TIME | ------------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 3 | 6063 | 2 (50)| 00:00:01 | |* 1 | COUNT STOPKEY | | | | | | | 2 | VIEW | | 3 | 6063 | 2 (50)| 00:00:01 | |* 3 | SORT ORDER BY STOPKEY | | 3 | 18351 | 2 (50)| 00:00:01 | | 4 | TABLE ACCESS BY INDEX ROWID| VTEXTE | 3 | 18351 | 1 (0)| 00:00:01 | | 5 | VECTOR INDEX HNSW SCAN | IDX_VTEXTE_HNSW_IDX | 3 | 18351 | 1 (0)| 00:00:01 |
;
Findet der Index Lauf die gleichen Daten wie ein full Table Scan?
SELECT INDEX_NAME,INDEX_SUBTYPE,TABLE_NAME FROM USER_INDEXES WHERE TABLE_NAME LIKE '%TEXTE%' AND index_type = 'VECTOR'; INDEX_NAME INDEX_SUBTYPE TABLE_NAME -------------------------------------------------------------------------------- IDX_VTEXTE_HNSW_IDX INMEMORY_NEIGHBOR_GRAPH_HNSW VTEXTE
Qualität bewerten:
SET serveroutput ON VARIABLE query_string VARCHAR2(1000) VARIABLE query_vector CLOB BEGIN :query_string := 'Die Katze steht auf der Hütte'; SELECT vector_embedding(ALL_MINILM_L6_V2 USING :query_string AS DATA) INTO :query_vector; END; / DECLARE v_qvector VECTOR; v_report varchar2(128); BEGIN v_qvector := to_vector(:query_vector); v_report := dbms_vector.index_accuracy_query( OWNER_NAME => 'GPI' , INDEX_NAME => 'IDX_VTEXTE_HNSW_IDX' , qv => v_qvector , top_K =>10 , target_accuracy =>90 ); dbms_output.put_line(v_report); END; / Accuracy achieved (100%) IS 10% higher than the Target Accuracy requested (90%)
Ein Vector kann auch mit Oracle Text kombiniert werden, siehe dazu ⇒ Oracle Datenbank 23ai - Hybrid Vector Search - Oracle Text und eine Model basierende AI Vector Index kombinieren
Mehr zu selbstdefinierten Vectoren ⇒ Oracle Datenbank 23ai - Mit Vectoren in der Oracle Datenbank Daten vergleichen - Demo Applikation für die Suche nach Farben
Ein Vector Index verwendet einen eigenen Pool Bereich in der Datenbank den „Vector Pool“, siehe https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/size-vector-pool.html
Der benötigt für komplexere Indexe dann auch eine gewisse Größe nach dem Motto „Nicht zu groß und nicht zu klein, gerade richtig muss es sein“ …. .
Was ist eingestellt:
sqlplus / AS sysdba SHOW parameter vector_memory_size NAME TYPE VALUE ------------------ ----------- ----- vector_memory_size big INTEGER 0 -- mit sqlplus im Container in der CDB anmelden und Parameter ändern podman EXEC -it freeDB bash bash-4.4$ su - oracle export ORACLE_HOME=/opt/oracle/product/23ai/dbhomeFree export ORACLE_SID=FREE export PATH=$ORACLE_HOME/bin:$PATH sqlplus / AS sysdba ALTER system SET vector_memory_size=512M scope=spfile; shutdown IMMEDIATE startup
Nun läßt sich der Index auch anlegen.
Web: