프린트 하기

OS 환경 : Oracle Linux 8.4 (64bit)

 

DB 환경 : Oracle Database 23.7.0.25.01, 23.9.0.25.07 ai for Oracle Cloud and Engineered Systems

 

방법 : 오라클 23ai 신기능 IVF Index Online Rebuild

오라클 23ai 23.9 버전부터 Inverted File Flat(IVF) Vector 인덱스를 온라인으로 rebuild 할수 있게됨
이 기능을 통해 dml 및 쿼리에 영향을 주지 않고 인덱스를 rebuild 할 수 있음
기존에는 벡터 분포가 바뀌면 인덱스 품질 저하와 검색 정확도 감소가 발생했고 이런 문제를 해결하려면 수동 drop 및 재생성해야 했음
이 기능을 통해 dml이 가능한 상태에서(online) ivf를 재생성해 인덱스의 품질을 향상시킬 수 있음

 

 

테스트
1. 23.7에서 ivf 인덱스 생성 및 rebuild 시도
2. 23.9에서 ivf 인덱스 생성 및 rebuild 시도

 

 

테스트
1. 23.7에서 ivf 인덱스 생성 및 rebuild 시도
버전 확인

1
2
3
4
5
SQL> select version_full from product_component_version;
 
VERSION_FULL
--------------------
23.7.0.25.01

 

 

샘플 테이블 생성

1
2
3
4
5
6
7
8
SQL>
drop table t1 purge;
create table t1 (c1, c2, c3, constraint t1_pk primary key (c1, c2)) as
select a.c1, b.c1, to_vector (json_array (a.c1, b.c1))
  from (select rownum as c1 from xmltable ('1 to 3')) a
     , (select rownum as c1 from xmltable ('1 to 3')) b;
 
Table created.

 

 

샘플 ivf 인덱스 생성

1
2
3
SQL> create vector index t1_x1 on t1 (c3) organization neighbor partitions distance euclidean with target accuracy 95;
 
Index created.

 

 

인덱스 사용하여 조회

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
SQL>
set autot on
set lines 200 pages 1000
col c3 for a20
select /*+ vector_index_transform(t1) */
c1, c2, c3, vector_distance (c3, '[1,1]', euclidean) as euclidean
from t1
where (c1, c2) != (1, 1)
order by vector_distance (c3, '[1,1]', euclidean)
fetch approx first 5 rows only;
 
        C1         C2 C3                    EUCLIDEAN
---------- ---------- -------------------- ----------
         2          1 [2.0E+000,1.0E+000]    1.0E+000
         1          2 [1.0E+000,2.0E+000]    1.0E+000
         2          2 [2.0E+000,2.0E+000]  1.414E+000
         1          3 [1.0E+000,3.0E+000]    2.0E+000
         3          1 [3.0E+000,1.0E+000]    2.0E+000
 
Execution Plan
----------------------------------------------------------
Plan hash value: 2809231042
 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                               | Name                                                    | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                        |                                                         |     5 | 20670 |    16  (13)| 00:00:01 |       |       |
|*  1 |  COUNT STOPKEY                          |                                                         |       |       |            |          |       |       |
|   2 |   VIEW                                  |                                                         |     5 | 20670 |    16  (13)| 00:00:01 |       |       |
|*  3 |    SORT ORDER BY STOPKEY                |                                                         |     5 |   720 |    16  (13)| 00:00:01 |       |       |
|*  4 |     HASH JOIN                           |                                                         |     5 |   720 |    15   (7)| 00:00:01 |       |       |
|   5 |      NESTED LOOPS                       |                                                         |     8 |  1128 |    11   (0)| 00:00:01 |       |       |
|*  6 |       TABLE ACCESS FULL                 | T1                                                      |     8 |   576 |     3   (0)| 00:00:01 |       |       |
|   7 |       TABLE ACCESS BY GLOBAL INDEX ROWID| VECTOR$T1_X1$28276_28280_0$IVF_FLAT_CENTROID_PARTITIONS |     1 |    69 |     1   (0)| 00:00:01 | ROWID | ROWID |
|*  8 |        INDEX UNIQUE SCAN                | SYS_C007673                                             |     1 |       |     0   (0)| 00:00:01 |       |       |
|   9 |      VIEW                               | VW_IVCR_2D77159E                                        |     6 |    18 |     4  (25)| 00:00:01 |       |       |
|* 10 |       COUNT STOPKEY                     |                                                         |       |       |            |          |       |       |
|  11 |        VIEW                             | VW_IVCN_9A1D2119                                        |     9 |   117 |     4  (25)| 00:00:01 |       |       |
|* 12 |         SORT ORDER BY STOPKEY           |                                                         |     9 |    81 |     4  (25)| 00:00:01 |       |       |
|  13 |          TABLE ACCESS FULL              | VECTOR$T1_X1$28276_28280_0$IVF_FLAT_CENTROIDS           |     9 |    81 |     3   (0)| 00:00:01 |       |       |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

인덱스 online rebuild 시도

1
2
3
4
5
6
SQL> alter index t1_x1 rebuild online;
alter index t1_x1 rebuild online
*
ERROR at line 1:
ORA-51926: Cannot alter an existing vector index
Help: https://docs.oracle.com/error-help/db/ora-51926/

에러가 발생함

 

 

인덱스 offline rebuild 시도

1
2
3
4
5
6
SQL> alter index t1_x1 rebuild;
alter index t1_x1 rebuild
*
ERROR at line 1:
ORA-51926: Cannot alter an existing vector index
Help: https://docs.oracle.com/error-help/db/ora-51926/

에러가 발생함

 

 

필요시 drop 후 재생성해야함

1
2
3
4
5
6
7
SQL> drop index t1_x1;
 
Index dropped.
 
SQL> create vector index t1_x1 on t1 (c3) organization neighbor partitions distance euclidean with target accuracy 95;
 
Index created.

 

 

2. 23.9에서 ivf 인덱스 생성 및 rebuild 시도
버전 확인

1
2
3
4
5
SQL> select version_full from product_component_version;
 
VERSION_FULL
--------------------
23.9.0.25.07

 

 

샘플 테이블 생성

1
2
3
4
5
6
7
8
SQL>
drop table t1 purge;
create table t1 (c1, c2, c3, constraint t1_pk primary key (c1, c2)) as
select a.c1, b.c1, to_vector (json_array (a.c1, b.c1))
  from (select rownum as c1 from xmltable ('1 to 3')) a
     , (select rownum as c1 from xmltable ('1 to 3')) b;
 
Table created.

 

 

샘플 ivf 인덱스 생성

1
2
3
SQL> create vector index t1_x1 on t1 (c3) organization neighbor partitions distance euclidean with target accuracy 95;
 
Index created.

 

 

인덱스 사용하여 조회

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
SQL>
set autot on
set lines 200 pages 1000
col c3 for a20
select /*+ vector_index_transform(t1) */
c1, c2, c3, vector_distance (c3, '[1,1]', euclidean) as euclidean
from t1
where (c1, c2) != (1, 1)
order by vector_distance (c3, '[1,1]', euclidean)
fetch approx first 5 rows only;
 
        C1         C2 C3                    EUCLIDEAN
---------- ---------- -------------------- ----------
         1          2 [1.0E+000,2.0E+000]    1.0E+000
         2          1 [2.0E+000,1.0E+000]    1.0E+000
         2          2 [2.0E+000,2.0E+000]  1.414E+000
         1          3 [1.0E+000,3.0E+000]    2.0E+000
         3          1 [3.0E+000,1.0E+000]    2.0E+000
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1106245971
 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                                                           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                                                                |     5 | 20670 |    28   (8)| 00:00:01 |       |       |
|*  1 |  COUNT STOPKEY                   |                                                                |       |       |            |          |       |       |
|   2 |   VIEW                           |                                                                |     5 | 20670 |    28   (8)| 00:00:01 |       |       |
|*  3 |    SORT ORDER BY STOPKEY         |                                                                |     5 |   410 |    28   (8)| 00:00:01 |       |       |
|*  4 |     HASH JOIN                    |                                                                |     5 |   410 |    27   (4)| 00:00:01 |       |       |
|   5 |      VIEW                        | VW_IVENJ_47D4581B                                              |     6 |    60 |    24   (5)| 00:00:01 |       |       |
|*  6 |       HASH JOIN                  |                                                                |     6 |   492 |    24   (5)| 00:00:01 |       |       |
|   7 |        PART JOIN FILTER CREATE   | :BF0000                                                        |     6 |    78 |     4  (25)| 00:00:01 |       |       |
|   8 |         VIEW                     | VW_IVCR_B5B87E67                                               |     6 |    78 |     4  (25)| 00:00:01 |       |       |
|*  9 |          COUNT STOPKEY           |                                                                |       |       |            |          |       |       |
|  10 |           VIEW                   | VW_IVCN_9A1D2119                                               |     9 |   117 |     4  (25)| 00:00:01 |       |       |
|* 11 |            SORT ORDER BY STOPKEY |                                                                |     9 |    81 |     4  (25)| 00:00:01 |       |       |
|  12 |             TABLE ACCESS FULL    | VECTOR$T1_X1$105110_105114_105197$IVF_FLAT_CENTROIDS           |     9 |    81 |     3   (0)| 00:00:01 |       |       |
|  13 |        PARTITION LIST JOIN-FILTER|                                                                |     9 |   621 |     3   (0)| 00:00:01 |:BF0000|:BF0000|
|  14 |         TABLE ACCESS FULL        | VECTOR$T1_X1$105110_105114_105197$IVF_FLAT_CENTROID_PARTITIONS |     9 |   621 |     3   (0)| 00:00:01 |:BF0000|:BF0000|
|* 15 |      TABLE ACCESS FULL           | T1                                                             |     8 |   576 |     3   (0)| 00:00:01 |       |       |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

인덱스 online rebuild 시도

1
2
3
SQL> alter index t1_x1 rebuild online;
 
Index altered.

정상적으로 rebuild됨

 

 

결론 :
23.9 이전 버전에서는 IVF 인덱스에 대한 online/offline rebuild 모두 허용되지 않았으며 ORA-51926 오류가 발생했음
하지만 23.9부터는 동일한 구문으로 online rebuild가 정상적으로 수행됨
ivf 인덱스를 온라인으로 rebuild 할 수 있게 됨에 따라 인덱스의 품질이 저하되어도 시스템 중단 없이 인덱스를 재구성할 수 있어 대규모 벡터 데이터를 다루는 환경에서 관리 효율성과 검색 성능이 모두 향상될 수 있음

 

 

참조 : 

https://apex.oracle.com/pls/apex/features/r/dbfeatures/features?feature_id=2070
https://docs.oracle.com/en/database/oracle/oracle-database/23/nfcoa/ru_23_9.html#GUID-102576-1
https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/inverted-file-flat-vector-indexes-online-rebuild.html#VECSE-GUID-FB09F02E-1EBE-4819-84D0-A387FD1C77F0
https://tuna.tistory.com/187