A row store that
wins the analytics.
On native Linux, over 1,000,000 rows, ElyraSQL 1.9.9 is the fastest of the three on every OLAP aggregation — 2–5× ahead of MySQL 8.4 and past PostgreSQL 17. Unusual for a row store.
on every OLAP aggregation over 1M rows
faster than MySQL on low-cardinality GROUP BY
faster than PostgreSQL on top-N GROUP BY
first stable release — SemVer from here on
Analytical queries
events(id, user_id, category, amount), 1M rows, each engine on its native schema. Milliseconds — lower is better.
| OLAP query | ElyraSQL 1.9.9 | PostgreSQL 17 | MySQL 8.4 |
|---|---|---|---|
| COUNT(*) | 25.2 ms | 28.7 ms | 24.0 ms |
| Global aggregation (SUM/AVG/MIN/MAX) | 35.9 ms | 45.1 ms | 162.4 ms |
| GROUP BY — low cardinality (100 groups) | 48.5 ms | 75.0 ms | 312.2 ms |
| GROUP BY + top-10 (10k groups) | 53.5 ms | 95.9 ms | 344.6 ms |
| Filtered aggregation (WHERE amount>500) | 50.5 ms | 54.5 ms | 229.5 ms |
Transactional workloads
Milliseconds — lower is better · ElyraSQL leads
Milliseconds — lower is better (all sub-millisecond)
PostgreSQL keeps a small edge on sub-millisecond point/range queries (mature tuple format + planner) — all already well under a millisecond.
LOAD DATA) — ahead of MySQL's ~290k.
ElyraSQL's crash-safe copy-on-write commit flushes more than a WAL append at tiny (2k-row) autocommit batches; at bulk-load sizes it pulls ahead.
| Workload | ElyraSQL 1.9.9 | PostgreSQL 17 | MySQL 8.4 |
|---|---|---|---|
| GROUP BY (full aggregation) | 9.8 ms | 16.1 ms | 21.4 ms |
| Full-scan COUNT (no index) | 9.3 ms | 10.4 ms | 20.8 ms |
| Bulk insert (rows/s) | 162,000 | 187,000 | 179,000 |
| Indexed COUNT | 0.90 ms | 1.21 ms | 0.65 ms |
| Selective join (index NLJ) | 0.39 ms | 0.24 ms | 0.45 ms |
| PK point lookup | 0.26 ms | 0.19 ms | 0.27 ms |
| Range + ORDER BY pk LIMIT | 0.85 ms | 0.30 ms | 0.85 ms |
How the OLAP speed happens
Vectorised grouped aggregation
GROUP BY on a numeric column keys each group in an FxHash map and accumulates into flat per-group f64/i64 arrays, decoding only the needed columns — no byte-key encoding or per-row Value dispatch. Top-10 GROUP BY 93 → 54 ms.
Single-pass hybrid spill
Aggregation keeps groups in memory and spills only the rows whose group does not fit to disk partitions — when the working set fits, nothing spills.
Streaming index nested-loop join
A JOIN on an indexed key with LIMIT scans the driving table incrementally, probes the partner per row and stops early — LIMIT 5 over 100k driving rows in ~0.5 ms, bounded memory.
Opt-in accelerators
ELYRASQL_SYNC=normal (~14× single-row insert throughput), ELYRASQL_COLUMN_CACHE_MB (cached unfiltered aggregations), and ELYRASQL_ZONE_MAPS (data-skipping for filtered aggregations) — all opt-in, default behaviour unchanged.
Native Linux, same host, same SQL
- All three engines run on one native x86_64 Linux runner (GitHub Actions ubuntu-latest, 4 cores).
- MySQL and PostgreSQL run as service containers on the same host; identical schema, rows and SQL.
- OLAP: 1M-row events table. Core SQL: 200k-row users/orders. Medians; ~10–20% run-to-run variance.
- ClickHouse is intentionally excluded — a columnar engine is a different architecture class, not a like-for-like row-store target.
# Native-Linux CI benchmark (the fair environment) $ gh workflow run benchmark.yml # Or run the harnesses locally $ python3 bench/olap.py # OLAP, 1M rows $ python3 bench/compare.py # core SQL, 200k rows
Run it yourself.
Download ElyraSQL 1.9.9 and reproduce the numbers on your own hardware.