0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OracleDB における完全ベクトル検索 (ENN) と近似ベクトル検索 (ANN)

0
Last updated at Posted at 2026-04-07

はじめに

ベクトル検索における完全ベクトル検索 (Exact Nearest Neighbor/ENN) と 近似ベクトル検索 (Approximate Nearest Neighbor/ANN) は、OracleDB では vector_distance()の後のFETCH FIRST n ROWS ONLYEXACTAPPROXIMATEを指定すると制御可能です。

どの程度検索速度に影響があるか確認してみます。

前提

4,096次元のベクトルデータを 25万件用意します。

SQL> CREATE TABLE testtab (
  2    vec VECTOR(4096, FLOAT32) NOT NULL
  3* );

Table TESTTAB created.

SQL> set timing on
SQL> INSERT /*+ APPEND */ INTO testtab (vec)
  2  SELECT v.vec
  3  FROM (
  4    SELECT LEVEL AS rn
  5    FROM dual
  6    CONNECT BY LEVEL <= 50000
  7  ) t
  8  CROSS APPLY (
  9    SELECT TO_VECTOR(
 10             JSON_ARRAYAGG(val ORDER BY dim RETURNING CLOB),
 11             4096,
 12             FLOAT32
 13           ) AS vec
 14    FROM (
 15      SELECT LEVEL AS dim,
 16             ROUND(DBMS_RANDOM.VALUE(0, 1) + 0 * t.rn, 6) AS val
 17      FROM dual
 18      CONNECT BY LEVEL <= 4096
 19    )
 20* ) v;

50,000 rows inserted.

Elapsed: 00:05:04.817
SQL> commit;

Commit complete.

Elapsed: 00:00:00.033

(snip)

SQL>
SQL> select count(1) from testtab;

   COUNT(1)
___________
     250000

Elapsed: 00:00:00.101
SQL> info testtab
TABLE: TESTTAB
         LAST ANALYZED:2026-04-03 01:30:45.0
         ROWS         :250000
         SAMPLE SIZE  :250000
         INMEMORY     :DISABLED
         COMMENTS     :

Columns
NAME         DATA TYPE                    NULL  DEFAULT    COMMENTS
 VEC         VECTOR(4096,FLOAT32,DENSE)   No


SQL>

次のような ENN の SQL と ANN の SQL を交互に実行し、実行時間を記録していきます。
(set timing onで表示される Elapsed を記録していきます)

ENN
VARIABLE qvec CLOB

BEGIN
  SELECT JSON_ARRAYAGG(
           ROUND(DBMS_RANDOM.VALUE(-1, 1), 6)
           ORDER BY dim
           RETURNING CLOB
         )
    INTO :qvec
    FROM (
      SELECT LEVEL AS dim
      FROM dual
      CONNECT BY LEVEL <= 4096
    );
END;
/
SELECT /*+ NO_RESULT_CACHE */ vec
FROM testtab
ORDER BY VECTOR_DISTANCE(vec, TO_VECTOR(:qvec, 4096, FLOAT32))
FETCH FIRST 10000 ROWS ONLY;
ANN
VARIABLE qvec CLOB

BEGIN
  SELECT JSON_ARRAYAGG(
           ROUND(DBMS_RANDOM.VALUE(-1, 1), 6)
           ORDER BY dim
           RETURNING CLOB
         )
    INTO :qvec
    FROM (
      SELECT LEVEL AS dim
      FROM dual
      CONNECT BY LEVEL <= 4096
    );
END;
/
SELECT /*+ NO_RESULT_CACHE */ vec
FROM testtab
ORDER BY VECTOR_DISTANCE(vec, TO_VECTOR(:qvec, 4096, FLOAT32))
FETCH APPROXIMATE FIRST 10000 ROWS ONLY;

環境は Autonomous AI Database (26ai) の Always Free です。

結果

結果は下記の通りとなりました。
念のためset autotrace traceonlyも設定していましたが、PHV に変化はありませんでした。

Elapsed SQLID PHV
1回目 (ENN) 00:01:30.456 fk3244cvb8kj6 3860506451
2回目 (ANN) 00:01:13.689 dsjuzpwyv3p6a 同上
3回目 (ENN) 00:01:27.028 fk3244cvb8kj6 同上
4回目 (ANN) 00:01:24.803 dsjuzpwyv3p6a 同上
5回目 (ENN) 00:01:29.389 fk3244cvb8kj6 同上
6回目 (ANN) 00:01:25.808 dsjuzpwyv3p6a 同上
7回目 (ENN) 00:01:29.345 fk3244cvb8kj6 同上
8回目 (ANN) 00:01:29.377 dsjuzpwyv3p6a 同上
9回目 (ENN) 00:01:27.563 fk3244cvb8kj6 同上
10回目 (ANN) 00:01:25.902 dsjuzpwyv3p6a 同上
11回目 (ENN) 00:01:26.004 fk3244cvb8kj6 同上
12回目 (ANN) 00:01:25.760 dsjuzpwyv3p6a 同上
13回目 (ENN) 00:01:23.380 fk3244cvb8kj6 同上
14回目 (ANN) 00:01:27.537 dsjuzpwyv3p6a 同上

参考までに、実行計画は下記のようになりました。

Plan hash value: 3860506451                                                                  
                                                                                             
--------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                       | E-Rows |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                            |        |       |       |          |
|   1 |  RESULT CACHE                 | 3kq35c2ds225753ga3b7622pcc |        | 65536 |  1024 |65536  (0)|
|*  2 |   COUNT STOPKEY               |                            |        |       |       |          |
|   3 |    PX COORDINATOR             |                            |        | 73728 | 73728 |          |
|   4 |     PX SEND QC (ORDER)        | :TQ10001                   |    250K|       |       |          |
|   5 |      VIEW                     |                            |    250K|       |       |          |
|*  6 |       SORT ORDER BY STOPKEY   |                            |    250K|  4410M|    20M|          |
|   7 |        PX RECEIVE             |                            |  10000 |       |       |          |
|   8 |         PX SEND RANGE         | :TQ10000                   |  10000 |       |       |          |
|*  9 |          SORT ORDER BY STOPKEY|                            |  10000 |   176M|  4464K|          |
|  10 |           PX BLOCK ITERATOR   |                            |    250K|       |       |          |
|* 11 |            TABLE ACCESS FULL  | TESTTAB                    |    250K|       |       |          |
--------------------------------------------------------------------------------------------------------

ENN と ANN の平均値は下記のようになりました。(1回目 (ENN) のみ除外して算出)
データにもよるとは思いますが、ANN の方が 2秒ほど早い結果となりました。
オンライントランザクションなど、数ミリ~数秒を争う世界でベクトル検索を利用する際には、ANN が良さそうです。(ENN で始めて、速度に問題があれば ANN を検討しましょう)

検索手法 平均値
ENN 01:27.118
ANN 01:24.697
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?