Local HNSW Indexes in Oracle AI Database 26ai: Partitioned Vector Search Without the Global Graph Rebuild

Branded header graphic for the blog post: Local HNSW Indexes in Oracle AI Database 26ai, partitioned vector search without the global graph rebuild
5–8 minutes

Who this is for: Oracle DBAs and developers running AI Vector Search on Oracle AI Database 26ai (formerly 23ai), especially anyone whose vector-indexed tables are large enough to already be partitioned.

A few months back I rebuilt a global HNSW index on a partitioned documents table (list-partitioned by region: US, EU, APAC) that backs a RAG search feature. The rebuild ran for just over three hours, and about halfway through I watched the Vector Memory Pool climb past what I’d sized in the SGA and start spilling. Nothing crashed, but the box got uncomfortably close to it, and I spent the next morning re-sizing memory instead of doing anything more useful. The whole time I kept thinking: I partitioned this table specifically so operations like this could be scoped to one region at a time. Why is the index build touching all of it at once?

Turns out Oracle had the same thought. The April 2026 quarterly release update for Oracle AI Database 26ai (Release Update 23.26.2) shipped local HNSW indexes: instead of one global HNSW graph spanning every row in a partitioned table, you get one independent graph per partition or subpartition.

Why This Matters

Oracle AI Database 26ai is the renamed, next-generation successor to 23ai. Oracle announced the rename and the on-premises roadmap in October 2025, and Enterprise Edition for Linux x86-64 went generally available on-premises as part of the January 2026 quarterly release update, version 23.26.1. AI Vector Search has been the flagship feature since the 23ai days, and it’s the piece most teams actually touch day to day: storing embeddings next to relational data, running similarity search for RAG pipelines, and increasingly building agentic workflows straight into the database.

The part that doesn’t get the keynote treatment is index maintenance at scale. An HNSW graph is fast to query but expensive to build and hold in memory, and a single global graph over a large partitioned table means every load, every reindex, and every memory-sizing decision has to account for the whole table at once, even when your actual queries almost always filter down to one partition first. Local HNSW indexes fix exactly that mismatch, and this release update also added function-based HNSW indexes, multi-vector search over IVF indexes, and IVF indexing on Iceberg external tables. Vector index performance is clearly getting the same iteration speed Oracle used to reserve for the B-tree.

What Local HNSW Indexes Actually Do

A local HNSW index builds one HNSW graph per partition (or subpartition) of an already-partitioned table, instead of one graph across the whole thing. The optimizer combines this with partition pruning: if your query’s WHERE clause narrows things down to a specific partition, only that partition’s local graph gets searched. Parallel execution goes further and can search multiple partitions’ graphs at once across CPU threads when a query legitimately spans more than one.

The syntax adds a single LOCAL keyword to the CREATE VECTOR INDEX statement you’d already be using:

CREATE VECTOR INDEX vidx_hnsw ON documents(embedding)
ORGANIZATION INMEMORY NEIGHBOR GRAPH
WITH TARGET ACCURACY 95
DISTANCE COSINE
PARAMETERS (type HNSW, neighbors 32, efConstruction 500)
LOCAL
PARALLEL 4;

And a query that filters on the partition key gets the benefit for free, no application changes needed:

SELECT id
FROM documents
WHERE region = 'US'
ORDER BY vector_distance(embedding, :query_vector)
FETCH FIRST 10 ROWS ONLY;
-- With a local HNSW index, only the US partition and its
-- local graph get searched. EU and APAC are pruned entirely.

On my documents table, rebuilding just the US partition’s graph after a data refresh now takes roughly a third of what the old global rebuild did, and the Vector Memory Pool sizing question became a per-partition problem instead of a whole-table one.

Where This Requires Care

The usage notes in Oracle’s documentation are worth reading in full before you touch a production table, because a few of these limitations will genuinely change how you sequence a migration. The base table has to already be partitioned; local HNSW indexes can’t be created on a non-partitioned table. More importantly, the base table has to be fully loaded with vector data before you create the index, and once the local HNSW index exists, DML on the indexed table (INSERT, UPDATE, DELETE) results in errors. This isn’t a background-sync situation like some other index types. You load first, then index, and after that the table is effectively read-only with respect to the indexed column until you rebuild.

A few other constraints worth knowing going in: there’s no online index creation for local HNSW, so plan for a maintenance window. Partition maintenance operations (splitting, merging, exchanging partitions) aren’t supported once the index is in place. Covering columns aren’t supported, and neither are sparse vector columns. Target accuracy, distance metric, and HNSW graph parameters (neighbors, efConstruction) are all set once and applied globally across every partition; you can’t tune one region’s graph differently from another’s, even if their data distributions genuinely differ.

Quick Reference: Working With Local HNSW Indexes

  • Load all vector data into the table before creating the index. Any load strategy that trickles data in afterward will fail once the index exists.
  • Size the SGA Vector Memory Pool per partition’s expected graph size, not the whole table, and confirm it during a test rebuild before you’re relying on it in production.
  • Use the PARALLEL clause during index creation. Local graphs are independent, so building them in parallel is close to free performance.
  • Design your partitioning key around your actual query filters first. A local HNSW index only pays off if queries can be pruned to one or a few partitions; if most of your queries scan across every partition anyway, a global HNSW index may still be the simpler choice.
  • Plan reindex windows around any partition maintenance. Since PMOPs aren’t supported with a local HNSW index in place, adding or exchanging a partition means dropping and recreating the index around that operation.

My Take

This is a genuinely useful feature, not a checkbox addition, but it arrived with the same trade-off Oracle partitioning has always carried: you get scalability in exchange for planning your access patterns up front, because retrofitting a partitioning strategy after the fact is painful with or without a vector index attached. The read-only-after-indexing behavior is the one I’d flag hardest to anyone building this into a pipeline that expects near-real-time updates; it pushes you toward a batch load and reindex cadence whether you’d planned for one or not.

Between local HNSW indexes, function-based HNSW indexes, and IVF indexing on Iceberg external tables all landing in the same release update, Oracle is iterating on vector index internals at roughly the pace it used to reserve for core relational features. If you’re running AI Vector Search on anything past a proof of concept, it’s worth checking the quarterly release update notes specifically, not just the headline 26ai announcements, because this is where the operationally relevant changes are actually showing up.

Further Reading