Saturday, May 16, 2026

AI/ML Inside Oracle Database: The Architecture That Wins

AI/ML Inside Oracle Database:

The Architecture That Wins


Scoring throughput
2M/sec
customers, no ETL
Per-prediction latency
<1ms
in-transaction scoring
Data staleness
0 hrs
scores at query time
Pipeline tax eliminated
6–18hr
typical ETL lag removed
ROI signal
Very High
Explosive 2026 adoption

Why 2026 Is the Inflection Point

Three forces have converged to make Oracle's in-database ML the most pragmatic enterprise AI bet in 2026. First, data gravity: your transactional data lives in Oracle — moving it costs real money in egress fees and real time in pipeline maintenance. Second, regulatory pressure: GDPR, CCPA, and emerging AI governance frameworks reward architectures where sensitive data never traverses a network boundary. Third, tooling maturity: OML4SQL, OML4Py, and AutoML have reached production-grade stability with Exadata acceleration — this is no longer experimental.

The fundamental architectural question enterprises are finally asking is not "which ML platform should we send our data to?" but "why are we paying to move 5TB of transaction logs nightly just to get back a churn score?"

5TB
Typical nightly data movement to external ML — replaced by zero with in-DB scoring
18hr
Maximum data staleness eliminated — models score against current rows, not yesterday's snapshot
False-negative cost multiplier in churn prediction — addressable via OML cost matrices
0
Additional governance tooling needed — Oracle security, audit, and masking apply automatically to all models

Full Architecture: The Oracle DB ML Boundary

The architecture below is the key insight. Everything — raw tables, feature engineering, model training, model storage, and scoring — happens inside a single Oracle Database boundary. The only thing that crosses the boundary is the result: a churn probability, an anomaly flag, a demand forecast. No raw PII, no transaction history, no training data ever leaves.

Oracle In-Database ML — Full Data & Model Lifecycle
ORACLE DATABASE BOUNDARY — NO DATA LEAVESRAW DATA LAYERTables / ViewsTransactions · LogsIoT StreamsOracle DB · ExadataERP / CRM DataSAP · Siebel bridgesHistorical MLPredictions → featuresONNX ModelsExternal importFEATURE ENGINEERING + TRAININGOML4SQL TransformsDBMS_DATA_MINING procsOML AutoML.fit()Algo select + hypertuningOML4Py TransparencyPython pushes to DB engineMODEL STORE — ALL_MINING_MODELSVersioned ModelsXGBoost · SVM · LSTMFull Audit TrailFGA · Unified AuditingExplain / InterpretPREDICTION_DETAILS()REAL-TIME INFERENCE — PREDICTION() INSIDE SELECTChurn PredictionXGBoost · 2M/secFraud On-CommitOne-Class SVM · <1msDemand ForecastESM / LSTM · ERP-nativeBUSINESS OUTCOMES — ONLY SCORES CROSS THE BOUNDARYBI DashboardsAlert QueuesERP / CRM ActionsFeedback loopv2026
Architect's Note

The feedback loop at the right of the diagram is deliberate and underappreciated. When prediction results are stored back into Oracle tables, they become new training features for the next model generation. A churn model that scores 2M customers today creates the labeled dataset that trains a better churn model next quarter — with zero additional ETL.

Anatomy of the Pipeline Tax

Every enterprise running an external ML platform pays a pipeline tax. Most of them don't itemize it. Here's what it actually costs:

External ML vs. In-Database ML — Pipeline Cost Comparison
EXTERNAL ML — THE PIPELINE TAXOracle DBRaw dataegress $ETL / ELT6–18 hr lagstale!ML PlatformSageMaker / AzureMLre-encryptScore APIREST roundtripingress $Oracle DBScores written backPIPELINE TAX• Egress fees• ETL infra + ops• Audit complexity• Stale predictionsORACLE IN-DB ML — ZERO PIPELINE TAXORACLE DATABASE — ALL OPERATIONS IN-PROCESSRaw Tablescurrent rowFeature ViewOML SQLModel StoreMINING_MODELSPREDICTION()in-SELECT · <1msELIMINATED✓ No egress✓ No ETL✓ Audit native✓ Live predictions

OML4SQL: DBA-Owned ML Workflows

OML4SQL is the most underrated feature in the Oracle stack. A DBA who already writes complex analytical SQL can build, train, evaluate, and score a production ML model without leaving the database console. There is no Python environment to maintain, no Jupyter notebook to share, no conda environment to version.

Churn Model: Full Training Pipeline

The following pipeline trains a gradient-boosted classifier, incorporates a business-aware cost matrix (false negatives cost 5× more than false positives), and scores 2 million customers in a single SELECT statement.

OML4SQL— churn_model_training_v2.sql
-- ①  Cost matrix: missing a churner costs 5× more than a false alarm
CREATE TABLE churn_cost_matrix (
    actual_target_value    VARCHAR2(10),
    predicted_target_value VARCHAR2(10),
    cost                   NUMBER
);
INSERT INTO churn_cost_matrix VALUES ('1', '0', 5);  -- FN: missed churner
INSERT INTO churn_cost_matrix VALUES ('0', '1', 1);  -- FP: unnecessary retention offer
COMMIT;

-- ②  Drop prior version safely
BEGIN
    DBMS_DATA_MINING.DROP_MODEL('CHURN_GB_MODEL_v2');
EXCEPTION WHEN OTHERS THEN NULL; END;
/

-- ③  Build the model with XGBoost and automatic preprocessing
DECLARE
    v_settings DBMS_DATA_MINING.SETTING_LIST;
BEGIN
    v_settings(DBMS_DATA_MINING.ALGO_NAME)
        := DBMS_DATA_MINING.ALGO_XGBOOST;
    v_settings(DBMS_DATA_MINING.PREP_AUTO)
        := DBMS_DATA_MINING.PREP_AUTO_ON;      -- handles nulls, encoding
    v_settings('XGBOOST_MAX_DEPTH')         := '6';
    v_settings('XGBOOST_N_ESTIMATORS')      := '300';
    v_settings('XGBOOST_LEARNING_RATE')     := '0.05';
    v_settings('XGBOOST_SUBSAMPLE')         := '0.8';
    v_settings('XGBOOST_COLSAMPLE_BYTREE')  := '0.8';
    v_settings(DBMS_DATA_MINING.CLAS_COST_TABLE_NAME)
        := 'CHURN_COST_MATRIX';

    DBMS_DATA_MINING.CREATE_MODEL2(
        model_name          => 'CHURN_GB_MODEL_v2',
        mining_function     => DBMS_DATA_MINING.CLASSIFICATION,
        data_query          => 'SELECT * FROM CHURN_TRAINING_VW',
        set_list            => v_settings,
        case_id_column_name => 'CUSTOMER_ID',
        target_column_name  => 'CHURNED_FLAG'
    );
END;
/

-- ④  Real-time scoring inside a SELECT — contracts expiring within 90 days
SELECT
    c.customer_id,
    c.customer_name,
    c.segment,
    c.contract_end_date,
    PREDICTION(CHURN_GB_MODEL_v2 USING c.*)                               AS churn_pred,
    ROUND(PREDICTION_PROBABILITY(CHURN_GB_MODEL_v2, 1 USING c.*) * 100, 2) AS churn_prob_pct,
    PREDICTION_DETAILS(CHURN_GB_MODEL_v2 USING c.*, 5)                      AS top5_drivers
FROM  customer_features_vw c
WHERE c.contract_end_date <= ADD_MONTHS(SYSDATE, 3)
ORDER BY churn_prob_pct DESC
FETCH FIRST 1000 ROWS ONLY;

-- ⑤  Evaluate model quality with full confusion matrix metrics
SELECT
    metric_name,
    ROUND(metric_value, 4) AS value
FROM TABLE(
    DBMS_DATA_MINING.COMPUTE_CONFUSION_MATRIX(
        accuracy           => NULL,
        apply_result_table => 'CHURN_SCORE_RESULT',
        target_table       => 'CHURN_TRAINING_VW',
        case_id_column     => 'CUSTOMER_ID',
        target_column      => 'CHURNED_FLAG'
    )
)
ORDER BY metric_name;

Advanced DBA Queries & Operational Patterns

Beyond the introductory train-and-score pattern, production deployments need model governance, drift monitoring, in-trigger scoring, and performance dashboards. These are the queries your senior DBA and ML engineer need on day one.

Model Registry & Version Governance

OML4SQL— model_governance.sql
-- List all models: algorithm, status, build date, owner
SELECT
    model_name,
    algorithm,
    mining_function,
    model_size_byte / 1024 / 1024    AS size_mb,
    build_duration                       AS train_seconds,
    TO_CHAR(creation_date, 'YYYY-MM-DD HH24:MI') AS created_at,
    owner
FROM  all_mining_models
ORDER BY creation_date DESC;

-- Model attribute importance — understand which features drive the model
SELECT
    attribute_name,
    attribute_subname,
    usage_type,
    ROUND(attribute_rank, 0) AS importance_rank
FROM  all_mining_model_attributes
WHERE model_name = 'CHURN_GB_MODEL_v2'
ORDER BY attribute_rank ASC NULLS LAST;

-- Capture model settings for audit / reproducibility
SELECT
    setting_name,
    setting_value,
    setting_type
FROM  all_mining_model_settings
WHERE model_name = 'CHURN_GB_MODEL_v2'
ORDER BY setting_name;

In-Trigger Fraud Scoring (On-Commit Path)

This pattern scores every payment transaction at the moment it is inserted — before the commit reaches the application. A fraud flag above 0.85 routes the row to a review queue automatically. Latency is under 1ms because there is no network hop.

OML4SQL— fraud_on_commit_trigger.sql
-- One-Class SVM anomaly model trained on legitimate transactions
DECLARE
    v_settings DBMS_DATA_MINING.SETTING_LIST;
BEGIN
    v_settings(DBMS_DATA_MINING.ALGO_NAME)
        := DBMS_DATA_MINING.ALGO_SUPPORT_VECTOR_MACHINES;
    v_settings(DBMS_DATA_MINING.SVMS_KERNEL_FUNCTION)
        := DBMS_DATA_MINING.SVMS_RBF;
    v_settings(DBMS_DATA_MINING.PREP_AUTO)
        := DBMS_DATA_MINING.PREP_AUTO_ON;
    v_settings(DBMS_DATA_MINING.CLAS_WEIGHTS_BALANCED)
        := DBMS_DATA_MINING.CLAS_WEIGHTS_AUTO;

    DBMS_DATA_MINING.CREATE_MODEL2(
        model_name          => 'FRAUD_SVM_v3',
        mining_function     => DBMS_DATA_MINING.ANOMALY_DETECTION,
        data_query          => 'SELECT * FROM LEGIT_TRANSACTIONS_VW',
        set_list            => v_settings,
        case_id_column_name => 'TXN_ID'
    );
END;
/

-- AFTER INSERT trigger: score in-flight, route anomalies immediately
CREATE OR REPLACE TRIGGER trg_fraud_score_on_insert
    AFTER INSERT ON payment_transactions
    FOR EACH ROW
DECLARE
    v_prob    NUMBER;
    v_details CLOB;
BEGIN
    -- Score the just-inserted row using the OML anomaly model
    SELECT
        PREDICTION_PROBABILITY(FRAUD_SVM_v3, 0 USING
            :NEW.amount,
            :NEW.merchant_category,
            :NEW.country_code,
            :NEW.card_present_flag,
            :NEW.hour_of_day,
            :NEW.avg_7d_spend,
            :NEW.velocity_15min
        ),
        PREDICTION_DETAILS(FRAUD_SVM_v3 USING
            :NEW.amount, :NEW.merchant_category, :NEW.country_code,
            :NEW.card_present_flag, :NEW.hour_of_day,
            :NEW.avg_7d_spend, :NEW.velocity_15min, 3
        )
    INTO v_prob, v_details
    FROM dual;

    -- Route high-probability anomalies to the review queue
    IF v_prob > 0.85 THEN
        INSERT INTO fraud_review_queue (
            txn_id, fraud_probability, oml_details, flagged_at
        ) VALUES (
            :NEW.txn_id, v_prob, v_details, SYSTIMESTAMP
        );
    END IF;
END;
/

Model Drift Monitoring Query

This query tracks prediction distribution week-over-week. A shift in average probability or class ratio without retraining is a leading indicator of model drift and requires investigation before silent degradation reaches business metrics.

OML4SQL— model_drift_monitor.sql
-- Weekly prediction distribution — alert if avg_prob shifts > 5 pp
WITH weekly_scores AS (
    SELECT
        TRUNC(score_date, 'IW')                       AS week_start,
        COUNT(*)                                        AS scored_rows,
        ROUND(AVG(churn_prob), 4)                      AS avg_prob,
        ROUND(STDDEV(churn_prob), 4)                   AS std_prob,
        ROUND(SUM(CASE WHEN churn_pred = 1 THEN 1 END)
              / COUNT(*), 4)                            AS positive_rate
    FROM  churn_score_history
    WHERE score_date >= ADD_MONTHS(SYSDATE, -3)
    GROUP BY TRUNC(score_date, 'IW')
),
drift_check AS (
    SELECT
        week_start,
        avg_prob,
        std_prob,
        positive_rate,
        LAG(avg_prob) OVER (ORDER BY week_start) AS prev_avg,
        ABS(avg_prob - LAG(avg_prob) OVER (ORDER BY week_start))
                                                     AS week_delta
    FROM  weekly_scores
)
SELECT
    week_start,
    avg_prob,
    positive_rate,
    week_delta,
    CASE
        WHEN week_delta > 0.05 THEN '⚠ DRIFT — RETRAIN CANDIDATE'
        WHEN week_delta > 0.02 THEN 'MONITOR'
        ELSE                        'STABLE'
    END AS drift_status
FROM  drift_check
ORDER BY week_start DESC;

Parallel Batch Scoring with Result Partitioning

OML4SQL— parallel_batch_score.sql
-- Parallel hint pushes scoring across Exadata cells
-- NOLOGGING + APPEND for max throughput on large batch writes
INSERT /*+ APPEND NOLOGGING */ INTO churn_score_snapshot
SELECT /*+ PARALLEL(c, 8) */
    c.customer_id,
    c.segment,
    c.region,
    PREDICTION(CHURN_GB_MODEL_v2 USING c.*)               AS churn_pred,
    PREDICTION_PROBABILITY(CHURN_GB_MODEL_v2, 1 USING c.*) AS churn_prob,
    SYSTIMESTAMP                                            AS scored_at
FROM customer_features_vw c;

COMMIT;

-- Segment-level summary for the dashboard — runs in seconds
SELECT
    segment,
    region,
    COUNT(*) AS total_customers,
    ROUND(AVG(churn_prob), 3) AS avg_churn_risk,
    SUM(CASE WHEN churn_prob >= 0.7 THEN 1 END) AS high_risk_count,
    ROUND(
        100 * SUM(CASE WHEN churn_prob >= 0.7 THEN 1 END) / COUNT(*), 1
    ) AS high_risk_pct
FROM  churn_score_snapshot
WHERE scored_at >= TRUNC(SYSDATE)
GROUP BY segment, region
ORDER BY avg_churn_risk DESC;

ONNX Model Import from External Training

When data science teams train on GPUs externally (e.g., a large demand forecasting LSTM that benefits from GPU acceleration), they can export to ONNX and import directly into Oracle — retaining the in-database scoring advantage without sacrificing training flexibility.

OML4SQL · ONNX— onnx_import.sql
-- Load a pre-trained ONNX model (trained externally, e.g. on GPU cluster)
EXECUTE DBMS_DATA_MINING.IMPORT_ONNX_MODEL(
    model_name    => 'DEMAND_LSTM_v1',
    model_data    => TO_BLOB(
        HEXTORAW('...')  -- real: load from BFILE or OBJ store
    ),
    metadata      => '{"function": "regression",
                        "input": ["lag_1","lag_7","lag_28",
                                  "day_of_week","promo_flag"],
                        "output": ["demand_forecast"]}'
);

-- Score with the LSTM exactly like a native OML model — same SQL syntax
SELECT
    sku_id,
    region,
    forecast_date,
    ROUND(
        PREDICTION(DEMAND_LSTM_v1 USING
            lag_1_demand, lag_7_demand, lag_28_demand,
            day_of_week, promo_flag
        ), 0
    ) AS predicted_units
FROM  demand_feature_vw
WHERE forecast_date BETWEEN SYSDATE AND SYSDATE + 14
ORDER BY sku_id, forecast_date;

OML4Py: Data Science Meets the Database Engine

The adoption blocker for in-database ML has always been tooling: DBAs are comfortable in SQL, data scientists live in Python. OML4Py dissolves this boundary. The data scientist writes Pandas-style code; OML4Py transparently pushes all heavy computation — sorting, aggregating, joining, model training — into the Oracle engine. No data is pulled into Python memory unless explicitly requested.

OML4Py— churn_workflow.py
import oml
import oml.automl
from oml.algo import XGBoostClassifier

# Connect: credentials stored in Oracle Wallet — no plaintext secrets
oml.connect(dsn="PROD_DB_HIGH")

# oml.sync() creates a proxy object — data stays IN the database
# This is NOT a Pandas DataFrame — no data is pulled into Python memory
features_proxy = oml.sync(table="CUSTOMER_FEATURES_VW", schema="ML_SCHEMA")

# All of these operations execute as SQL inside Oracle
high_value = features_proxy[features_proxy["SEGMENT"] == "ENTERPRISE"]
train_data = high_value.drop("CUSTOMER_ID")

# XGBoost training — executes inside the DB engine, not Python
xgb_clf = XGBoostClassifier(
    max_depth=6,
    n_estimators=300,
    learning_rate=0.05,
    eval_metric="logloss"
)
xgb_clf.fit(
    X=train_data.drop("CHURNED_FLAG"),
    y=train_data["CHURNED_FLAG"],
    case_id="CUSTOMER_ID"
)

# Model is now in ALL_MINING_MODELS — query it with SQL from anywhere
print(xgb_clf.model_name)          # OML$XGB$0001 (or your named alias)

# Evaluate: stays in DB, returns lightweight Python dict
test_proxy  = oml.sync(query="SELECT * FROM CHURN_TEST_VW")
predictions = xgb_clf.predict(test_proxy.drop("CHURNED_FLAG"))
accuracy    = xgb_clf.score(test_proxy.drop("CHURNED_FLAG"),
                              test_proxy["CHURNED_FLAG"])
print(f"Accuracy: {accuracy:.3f}")

# Feature importance — bring ONLY this small result to Python memory
importance_df = xgb_clf.feature_importances_
print(importance_df.to_pandas().sort_values("IMPORTANCE", ascending=False).head(10))

AutoML: From Feature View to Production in One Call

Oracle AutoML performs algorithm selection, feature selection, hyperparameter tuning, and model selection automatically. For a DBA or product team that wants ML value without deep ML expertise, this is the fastest path from a feature view to a production model.

OML4Py · AutoML— automl_pipeline.py
import oml
import oml.automl

oml.connect(dsn="PROD_DB_HIGH")

training_view = oml.sync(table="CHURN_TRAINING_VW")

# AutoML selects the best algorithm, feature set, and hyperparameters
# All computation runs inside Oracle — no external MLflow, no Optuna
automl = oml.automl.AutoML2(
    mining_function   = "CLASSIFICATION",
    time_budget       = 3600,   # 1-hour budget for search
    parallel_level    = 8,      # use 8 parallel DB sessions
    cv_num_folds      = 5,
    optimization_metric = "F1"  # optimize for F1, not accuracy
)

best_model, metric, algo = automl.fit(
    X      = training_view.drop("CHURNED_FLAG"),
    y      = training_view["CHURNED_FLAG"],
    case_id = "CUSTOMER_ID"
)

print(f"Best algorithm : {algo}")
print(f"Best F1 score  : {metric:.4f}")
print(f"Model name     : {best_model.model_name}")

# Retrieve all candidate models ranked by metric (full leaderboard)
leaderboard = automl.get_algorithm_rankings()
print(leaderboard.to_pandas()[["Algorithm", "F1", "AUC"]])

Governance by Default, Not Bolt-On

This is the architectural argument that closes deals. When you build ML on an external platform, you must separately implement data masking, access control, audit logging, and lineage — and keep all of it synchronized with your Oracle security policies. When you train and score inside Oracle, you get all of this for free as a structural property of the architecture.

Governance RequirementExternal ML PlatformOracle In-DB ML
PII maskingCustom pipeline step requiredOracle Data Masking inherits automatically
Access controlSeparate IAM + platform RBACOracle VPD + GRANT model on ALL_MINING_MODELS
Training data lineageExternal MLflow / manual taggingCREATE_MODEL2 records query at model creation time
Prediction auditApp-level logging requiredOracle Unified Auditing covers PREDICTION() calls
GDPR right-to-erasureMust purge from DB + platform + feature storeDelete row in Oracle; model auto-excludes via re-train
Model explainability (GDPR Art. 22)SHAP values in separate notebookPREDICTION_DETAILS() returns top-N drivers inline
Encryption at restPlatform + Oracle TDE — two policiesOracle TDE covers models + data — one policy
OML4SQL— governance_grants.sql
-- Grant scoring rights without exposing raw training data
GRANT SELECT ON customer_features_vw  TO ml_scoring_role;
GRANT SELECT ON all_mining_models      TO ml_ops_role;

-- Revoke training rights from scoring role (separation of duties)
REVOKE EXECUTE ON dbms_data_mining FROM ml_scoring_role;

-- Fine-grained audit: log every PREDICTION() call that scores PII
BEGIN
    DBMS_FGA.ADD_POLICY(
        object_schema    => 'ML_SCHEMA',
        object_name      => 'CUSTOMER_FEATURES_VW',
        policy_name      => 'AUDIT_ML_SCORING',
        audit_condition  => NULL,            -- audit all access
        audit_column     => 'EMAIL,PHONE_NUMBER',
        handler_schema   => NULL,
        handler_module   => NULL,
        enable           => TRUE
    );
END;
/

-- Verify model security metadata
SELECT
    model_name,
    owner,
    TO_CHAR(creation_date, 'YYYY-MM-DD') AS created,
    algorithm,
    mining_function
FROM  all_mining_models
WHERE model_name LIKE 'CHURN%'
ORDER BY creation_date DESC;

The Architect's Take: When Not to Use In-DB ML

Intellectual honesty requires acknowledging the boundaries of this pattern. In-database ML is the right call for most enterprise Oracle deployments — but not all of them.

When to choose an external platform instead

Training on unstructured data at scale. If your primary signal is images, video, audio, or large unstructured text and you need a foundation model fine-tuned on GPUs, Oracle is not the training environment. Import the resulting ONNX model for inference.

Experimentation velocity over governance. Early-stage R&D with data scientists who need rapid experiment iteration, MLflow tracking, and a Jupyter-centric workflow will move faster in an external MLOps platform. Once you have a validated model, import it via ONNX.

Non-Oracle primary data stores. If your primary data is in Snowflake, BigQuery, or a lakehouse, the gravity argument reverses. Don't force data into Oracle just to use OML.

Real-time serving at extreme scale (>10K RPS) outside a DB context. At pure API serving scale with no database interaction, a dedicated model serving layer (Triton, TorchServe) may outperform.

The hybrid playbook (recommended for most enterprises)

Train externally, import via ONNX, score in-database. This captures the best of both worlds: GPU-accelerated training in a modern MLOps environment, combined with Oracle's governance, latency, and data gravity advantages at inference time. The ONNX bridge is the critical integration point — validate your model's ONNX export early in the architecture process, not after.

Adoption Playbook for Product Owners

From a product ownership perspective, in-database ML has an unusual adoption dynamic: it requires selling to two audiences simultaneously with different priorities — and it wins both arguments.

Selling to the DBA / Platform Team

Frame it as reducing operational surface area. Every external ML pipeline introduces a new failure domain, a new security perimeter to maintain, and a new cost center. OML4SQL eliminates all three. Governance is automatic. There is no feature store to synchronize. The DBA already controls the data; now they control the models too.

Selling to the Data Science Team

Frame it as removing the deployment gap. The most painful part of enterprise ML is not training — it's deploying. Getting a model from a Jupyter notebook to production typically takes weeks of engineering work. With OML4Py, the Python code that trains the model and the SQL that scores in production share the same model artifact. Deployment is a GRANT statement.

Selling to Finance

Frame it as stranded capacity utilization. Every Oracle Enterprise License customer is already paying for OML. The incremental cost is configuration, not licensing. Compare that against $50K–$200K/year for an external ML platform plus the FTE cost of maintaining the ETL pipeline between them.


No comments:

Post a Comment

Multi-Cloud - OCI, Azure, and AWS

Why Multi-Cloud Is Not Optional in 2026 Three converging forces have made Oracle's co-location model the default enterprise architecture...