In the previous
blog post we explored how AI vector search allows you to find similar
content based on semantic representation or meaning rather than the actual
(raw) values. In that examples we performed exhaustive similarity searches,
comparing each item in the dataset to find the closest matches, while this
approach helps guarantee accuracy, it doesn’t scale well. (think of searching
thorough millions or billions of vectors one by one!)
This is where
the vector index comes in, instead of checking every possible matches, an
approximate similarity search uses a class of algorithms referred to as
Approximate nearest neighbour. Using vector indexes helps to reduce the number
of distance calculations, making searches faster and more efficient in accuracy
The example we
used from the previous
blog post performed exhaustive similarity searches, An exhaustive search to
find the closest match for a given query vector are accurate, but can be slow ,
since the vector distance computation are needed for all vectors in that
column.
demo@ADB26AI> select
case_primary_type , case_description , vd
2 from (
3 select case_primary_type
4 , case_description
5 , vector_distance(case_embeddings , vector_embedding( MY_DEMO_MODEL using 'LARCENY' as data ) , cosine ) vd
6 from vector_search_demo t
7 order by vd
8 fetch exact first 500 rows only)
9 group by case_primary_type , case_description ,vd
10 order by vd
11 fetch first 15 rows only;
CASE_PRIMARY_TYPE CASE_DESCRIPTION VD
------------------------- --------------------------------------------- ----------
OTHER OFFENSE OTHER CRIME INVOLVING PROPERTY 3.845E-001
And the
execution plan is the following
demo@ADB26AI> select *
from table( dbms_xplan.display_cursor(format=>'allstats last'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------
SQL_ID 53rn6381kurk1, child number 0
-------------------------------------
select case_primary_type , case_description , vd from ( select
case_primary_type , case_description ,
vector_distance(case_embeddings , vector_embedding( MY_DEMO_MODEL using
'LARCENY' as data ) , cosine ) vd from vector_search_demo t
order by vd fetch exact first 500 rows only) group by
case_primary_type , case_description ,vd order by vd fetch first 15
rows only
Plan hash value: 1825924980
---------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.78 | 27455 | 27453 |
| 1 | RESULT CACHE | 6msm9kz3v36qg9v5yj4| 1 | | 1 |00:00:00.78 | 27455 | 27453 |
|* 2 | COUNT STOPKEY | | 1 | | 1 |00:00:00.78 | 27455 | 27453 |
| 3 | VIEW | | 1 | 500 | 1 |00:00:00.78 | 27455 | 27453 |
|* 4 | SORT GROUP BY STOPKEY | | 1 | 500 | 1 |00:00:00.78 | 27455 | 27453 |
| 5 | VIEW | | 1 | 500 | 500 |00:00:00.78 | 27455 | 27453 |
|* 6 | COUNT STOPKEY | | 1 | | 500 |00:00:00.78 | 27455 | 27453 |
| 7 | VIEW | | 1 | 1427K| 500 |00:00:00.78 | 27455 | 27453 |
|* 8 | SORT ORDER BY STOPKEY | | 1 | 1427K| 500 |00:00:00.78 | 27455 | 27453 |
| 9 | TABLE ACCESS STORAGE FULL| VECTOR_SEARCH_DEMO | 1 | 1427K| 1427K|00:00:00.43 | 27455 | 27453 |
---------------------------------------------------------------------------------------------------------------------------
Predicate Information
(identified by operation id):
---------------------------------------------------
2 - filter(ROWNUM<=15)
4 - filter(ROWNUM<=15)
6 - filter(ROWNUM<=500)
8 - filter(ROWNUM<=500)
Since we have
no indexes defined, we see a full table scan access to the target table (id :
9 - TABLE ACCESS STORAGE FULL)
There are
currently three types of vector indexes available in AI Vector search, and one
among them is in-memory neighbour graph vector index also called as in-memory
Hierarchical Navigable small world (HNSW). It is a type of in-memory Neighbour
graph vector index , where the vertices represent vectors and the edges between
the vertices represent similarity. This is an in-memory only index, this type
of index is highly efficient for both accuracy and speed.
2 from (
3 select case_primary_type
4 , case_description
5 , vector_distance(case_embeddings , vector_embedding( MY_DEMO_MODEL using 'LARCENY' as data ) , cosine ) vd
6 from vector_search_demo t
7 order by vd
8 fetch exact first 500 rows only)
9 group by case_primary_type , case_description ,vd
10 order by vd
11 fetch first 15 rows only;
------------------------- --------------------------------------------- ----------
OTHER OFFENSE OTHER CRIME INVOLVING PROPERTY 3.845E-001
-----------------------------------------------------------------------
SQL_ID 53rn6381kurk1, child number 0
-------------------------------------
select case_primary_type , case_description , vd from ( select
case_primary_type , case_description ,
vector_distance(case_embeddings , vector_embedding( MY_DEMO_MODEL using
'LARCENY' as data ) , cosine ) vd from vector_search_demo t
order by vd fetch exact first 500 rows only) group by
case_primary_type , case_description ,vd order by vd fetch first 15
rows only
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.78 | 27455 | 27453 |
| 1 | RESULT CACHE | 6msm9kz3v36qg9v5yj4| 1 | | 1 |00:00:00.78 | 27455 | 27453 |
|* 2 | COUNT STOPKEY | | 1 | | 1 |00:00:00.78 | 27455 | 27453 |
| 3 | VIEW | | 1 | 500 | 1 |00:00:00.78 | 27455 | 27453 |
|* 4 | SORT GROUP BY STOPKEY | | 1 | 500 | 1 |00:00:00.78 | 27455 | 27453 |
| 5 | VIEW | | 1 | 500 | 500 |00:00:00.78 | 27455 | 27453 |
|* 6 | COUNT STOPKEY | | 1 | | 500 |00:00:00.78 | 27455 | 27453 |
| 7 | VIEW | | 1 | 1427K| 500 |00:00:00.78 | 27455 | 27453 |
|* 8 | SORT ORDER BY STOPKEY | | 1 | 1427K| 500 |00:00:00.78 | 27455 | 27453 |
| 9 | TABLE ACCESS STORAGE FULL| VECTOR_SEARCH_DEMO | 1 | 1427K| 1427K|00:00:00.43 | 27455 | 27453 |
---------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------
4 - filter(ROWNUM<=15)
6 - filter(ROWNUM<=500)
8 - filter(ROWNUM<=500)
------------------------------------ ----------- -----------
vector_memory_size big integer 83383634
2 from v$vector_memory_pool;
-------------------------- ----------- ---------- -------------------------- ----------
1MB POOL 58368543 62914560 OUT OF MEMORY 37
64KB POOL 22930499 2359296 DONE 37
demo@ADB26AI> begin
2 dbms_vector.index_vector_memory_advisor(
3 table_owner => user
4 , table_name => 'VECTOR_SEARCH_DEMO'
5 , column_name => 'CASE_EMBEDDINGS'
6 , index_type => 'HNSW'
7 , response_json => :r );
8 end;
9 /
Using default accuracy: 90%
Suggested vector memory pool size: 3 GB
-------------- ----------- --------
sga_target big integer 13600M
2 on VECTOR_SEARCH_DEMO( CASE_EMBEDDINGS )
3 organization inmemory neighbor graph
4 distance cosine
5 with target accuracy 90;
2 , used_bytes, num_vectors, index_dimensions
3 from v$vector_index
4 where owner = user;
--------------- ------------------------- --------------- ---------- ----------- ----------------
HNSW_DEMO INMEMORY NEIGHBOR GRAPH 2619080704 2613867800 1427029 384
2 from v$vector_memory_pool;
------------ ----------- ---------- --------------- ----------
1MB POOL 2945554763 2658140160 DONE 37
64KB POOL 447608812 26738688 DONE 37
------------------------------------ ----------- ---------
vector_index_neighbor_graph_reload string RESTART
2 from (
3 select case_primary_type
4 , case_description
5 , vector_distance(case_embeddings , vector_embedding( MY_DEMO_MODEL using 'LARCENY' as data ) , cosine ) vd
6 from vector_search_demo t
7 order by vd
8 fetch approx first 500 rows only with target accuracy 90 )
9 group by case_primary_type , case_description ,vd
10 order by vd
11 fetch first 15 rows only;
------------------------- --------------------------------------------- ----------
OTHER OFFENSE OTHER CRIME INVOLVING PROPERTY 3.845E-001
OTHER OFFENSE OTHER CRIME AGAINST PERSON 3.949E-001
---------------------------------------------------------------------------------------
SQL_ID amk960c8v78xa, child number 0
-------------------------------------
select case_primary_type , case_description , vd from ( select
case_primary_type , case_description ,
vector_distance(case_embeddings , vector_embedding( MY_DEMO_MODEL using
'LARCENY' as data ) , cosine ) vd from vector_search_demo t
order by vd fetch approx first 500 rows only with target accuracy
90 ) group by case_primary_type , case_description ,vd order by vd
fetch first 15 rows only
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2 |00:00:00.01 | 1260 | 7 |
| 1 | RESULT CACHE | 6xt3798pj66dtdndjw | 1 | | 2 |00:00:00.01 | 1260 | 7 |
|* 2 | COUNT STOPKEY | | 1 | | 2 |00:00:00.01 | 1260 | 7 |
| 3 | VIEW | | 1 | 500 | 2 |00:00:00.01 | 1260 | 7 |
|* 4 | SORT GROUP BY STOPKEY | | 1 | 500 | 2 |00:00:00.01 | 1260 | 7 |
| 5 | VIEW | | 1 | 500 | 500 |00:00:00.01 | 1260 | 7 |
|* 6 | COUNT STOPKEY | | 1 | | 500 |00:00:00.01 | 1260 | 7 |
| 7 | VIEW | | 1 | 500 | 500 |00:00:00.01 | 1260 | 7 |
|* 8 | SORT ORDER BY STOPKEY | | 1 | 500 | 500 |00:00:00.01 | 1260 | 7 |
| 9 | TABLE ACCESS BY INDEX ROWID| VECTOR_SEARCH_DEMO | 1 | 500 | 500 |00:00:00.01 | 1260 | 7 |
| 10 | VECTOR INDEX HNSW SCAN | HNSW_DEMO | 1 | 500 | 500 |00:00:00.01 | 2 | 0 |
---------------------------------------------------
4 - filter(ROWNUM<=15)
6 - filter(ROWNUM<=500)
8 - filter(ROWNUM<=500)

No comments:
Post a Comment