Tested on: Oracle AI Database 26ai (23.26.4.1.0) on Oracle Autonomous AI Database, in-database ONNX model ALL_MINILM_L12_V2 | Level: Intermediate
Customers rarely use the words a support team expects. "Someone took my card" means the same as "my debit card is missing", but a keyword search will not find one from the other. I loaded an AI embedding model directly into Oracle AI Database 26ai and ran semantic search over 2,000 fictional bank support tickets, with no external AI service involved. For five of six customer questions worded unlike any ticket, at least 8 of the top 10 results were the right kind of ticket. Embedding ran at about 73 tickets per second, and a search took under 1 ms with an HNSW index. The sixth question failed completely, and the reason why is the most useful lesson in this post.
Results at a glance
| Step | Measured |
|---|---|
| Download and load the ONNX model into the database | 23.7 s |
| Embed 2,000 tickets inside the database | 27.4 s (about 73 tickets/s) |
| Embed one customer question | 15.8 ms |
| Top-10 search, exact scan | 1.55 ms |
| Build HNSW vector index | 1.8 s |
| Top-10 search, HNSW index | 0.82 ms |
| Questions answered correctly (at least 8 of top 10) | 5 of 6 |
Why semantic search, and why inside the database
An embedding model turns a piece of text into a vector, a list of numbers that represents its meaning. Texts with similar meaning get vectors that are close together, even when they share no words. Searching by vector distance finds tickets about the same problem, however the customer phrased it.
Oracle AI Database 26ai can run such a model inside the database in ONNX format. Embeddings are generated with SQL, next to the data, so customer text never leaves the database to reach an external AI service. For a bank, that is a significant data-protection advantage.
Step 1: load the model
Oracle publishes a prebuilt version of the all-MiniLM-L12-v2 sentence model for the database. On Autonomous Database it is downloaded into DATA_PUMP_DIR and then loaded:
DECLARE
l_file VARCHAR2(100) := 'all_MiniLM_L12_v2.onnx';
l_uri VARCHAR2(1000) := '<Oracle model bucket URL>/' || 'all_MiniLM_L12_v2.onnx';
BEGIN
DBMS_CLOUD.GET_OBJECT(credential_name => NULL,
directory_name => 'DATA_PUMP_DIR',
object_uri => l_uri);
DBMS_VECTOR.LOAD_ONNX_MODEL(directory => 'DATA_PUMP_DIR',
file_name => l_file,
model_name => 'ALL_MINILM_L12_V2');
END;
/
The download URL is in Oracle's blog post "Use our prebuilt ONNX model now available for embedding generation in Oracle Database 23ai". Loading took 23.7 seconds, and the model appears like any other mining model:
MODEL_NAME MINING_FUNCTION ALGORITHM
----------------- --------------- ---------
ALL_MINILM_L12_V2 EMBEDDING ONNX
DIMENSIONS
----------
384
Step 2: tickets and embeddings
I generated 2,000 fictional tickets across eight categories: lost card, failed transfer, login and OTP, ATM cash, loan EMI, fees, KYC and statements. Each category has six different wordings, for example "Lost ATM card, please deactivate it" and "My wallet with the bank card was taken".
CREATE TABLE sem_tickets (
ticket_id NUMBER PRIMARY KEY,
category VARCHAR2(20),
ticket_text VARCHAR2(400),
embedding VECTOR(384, FLOAT32)
);
UPDATE sem_tickets
SET embedding = VECTOR_EMBEDDING(ALL_MINILM_L12_V2 USING ticket_text AS data);
One UPDATE embedded all 2,000 tickets in 27.4 seconds, about 73 tickets per second on this sandbox. Embedding a single customer question took 15.8 ms.
Step 3: keyword vs semantic
I wrote six customer questions on purpose so that none of them uses the wording of any ticket. Keyword search took one obvious word from each question, such as "took", "mortgage" or "security".
SELECT category
FROM sem_tickets
ORDER BY VECTOR_DISTANCE(embedding, :question_vector, COSINE)
FETCH EXACT FIRST 10 ROWS ONLY;
QUESTION KEYWORD_HITS SEMANTIC_CORRECT_OF_10
-------------------------------------------- ------------ ----------------------
someone took my card 0 10
I paid a friend but he never got the money 0 8
the security code text message is not coming 0 10
the cash point kept my money 0 10
monthly repayment amount for my mortgage 0 10
the bank took extra money without telling me 0 0
Keyword search found nothing for any question. To be fair to it, that is by design: I chose questions worded differently from every ticket, which is exactly where keyword search is weakest. Semantic search, by contrast, found the right category for five of six questions. The top match for "someone took my card" was a ticket that shares almost no words with it (duplicate row removed):
TICKET_TEXT CATEGORY DISTANCE
------------------------------------------------ ---------- --------
My wallet with the bank card was taken. Thanks. CARD_LOST 0.28
I think someone stole my credit card. Thanks. CARD_LOST 0.28
The miss: when words outweigh meaning
The question "the bank took extra money without telling me" is about a fee. Every one of its top five results was a lost-card ticket (trimmed):
CATEGORY TICKET_TEXT DISTANCE
---------- --------------------------------------------------------------- --------
CARD_LOST My wallet with the bank card was taken. Happened yesterday... 0.417
CARD_LOST My wallet with the bank card was taken. Customer called twice. 0.428
The model latched onto the shared words "bank" and "took/taken" instead of the meaning, an unexpected charge. The transfer question showed a milder version of the same effect. Its top result was an ATM ticket at distance 0.513, against 0.514 for the correct transfer tickets: "money was deducted but did not arrive" describes both problems.
This is the practical lesson. A small, general-purpose embedding model is good at paraphrases but can still be pulled by overlapping words, especially in short texts. Before relying on it, test it with real customer phrasings, and consider:
- A stronger or domain-tuned embedding model, loaded into the database the same way.
- Hybrid search, combining keyword and vector relevance. Oracle AI Database also supports hybrid vector indexes for this.
- Richer ticket text, such as the agent's resolution notes, which give the model more meaning to work with than a one-line complaint.
- Showing several top results to the support agent instead of auto-routing on the first match.
Step 4: search speed
CREATE VECTOR INDEX sem_hnsw_idx ON sem_tickets (embedding)
ORGANIZATION INMEMORY NEIGHBOR GRAPH
DISTANCE COSINE
WITH TARGET ACCURACY 95;
With 2,000 tickets, a top-10 search took 1.55 ms as an exact scan and 0.82 ms with the HNSW index, which built in 1.8 seconds. At this size both are fast. The bigger cost in a real request is embedding the question itself (15.8 ms), so for interactive search, plan capacity around the model, not just the index.
Things to know before using it
- Embedding throughput sets your load time. At about 73 tickets per second on this sandbox, a million tickets would take hours. Embed in batches, and embed new tickets as they arrive.
- Re-embed when you change the model. Vectors from different models cannot be compared, so a model upgrade means re-embedding the whole table.
- Duplicates fill the top 10. My generated data repeats some ticket texts, so several top results were identical. Real data has more variety, but de-duplicating similar tickets makes results more useful.
- The data stays in the database. No ticket text was sent to an external service, which keeps the data-protection review simple.
Clean-up
DROP TABLE sem_tickets PURGE;
DROP TABLE sem_queries PURGE;
EXEC DBMS_DATA_MINING.DROP_MODEL('ALL_MINILM_L12_V2')
Summary
Oracle AI Database 26ai ran an AI embedding model inside the database and turned 2,000 bank support tickets into searchable vectors in under half a minute, with no external AI service. Semantic search understood five of six customer questions that keyword search could not match at all, with searches well under 2 ms. The sixth question showed the limit: a small general model can be pulled by shared words like "bank" and "took". Test with real customer language, and add hybrid search or a stronger model where precision matters.
Lab design, testing and all results are my own, run on an Oracle LiveLabs sandbox.
Tamilselvan Perumal is an Oracle ACE Apprentice and Senior DBA with 12+ years in banking databases, working on database performance and benchmarking. Connect on LinkedIn.
.png)
.png)