Performance
Elyra DataGrid is built to stay fast at scale by pushing work to the database and keeping both the DOM and the query cost bounded.
For measured numbers on a 10M-row table (and how to reproduce them), see Benchmarks.
Principles
- O(viewport), never O(data). Only the visible window of rows is fetched and rendered. Row virtualization (Svelte/Vue) and column virtualization keep the DOM small regardless of dataset or column count.
- Opt-in cost. Nothing expensive runs unless a feature needs it:
total(row count) and footeraggregatesare requested only when paging / aggregates are enabled, and are cached per filter — paging or sorting does not recompute them.- Facets are lazy — computed only when a filter dropdown opens, and cached until the filter changes.
- Push down to SQL. Sorting, filtering, grouping, aggregation and search execute in ElyraSQL, not in JavaScript.
- Stream exports. Exports read from a server cursor, so memory is constant even for millions of rows.
- Server-seeded first paint.
initialDatarenders the first page instantly without waiting for a client round-trip.
Measured behavior (10M-row table, ElyraSQL)
| Interaction | Cost |
|---|---|
| First render (per filter) | ~total + aggregates (one-time) |
| Paging / sorting (same filter) | ~viewport query only (totals cached) |
| Opening a filter dropdown | one lazy FACET() (cached after) |
| Export | streamed, constant memory |
In practice, once a filter is set, paging is dominated by the viewport query and the cached totals are reused — subsequent pages are effectively instant.
Indexing guidance (ElyraSQL)
- Index columns used in selective
WHEREfilters — filteredCOUNT/aggregates become index reads instead of full scans. - Prefer grouping/faceting on lower-cardinality columns (memory is proportional to the number of groups, not rows).
- Keep
meta: ['total']opt-in on very large unfiltered sets if you do not need an exact count.
Known engine consideration
Sorting at scale depends on ElyraSQL's index-backed top-N. Measured on a 10M-row table (ElyraSQL 1.4.5):
| Query shape | Cost |
|---|---|
ORDER BY id [DESC] LIMIT n (primary key) |
~50 ms |
ORDER BY <indexed_col> DESC LIMIT n |
~50 ms (index-backed top-N) |
ORDER BY <indexed_col> ASC LIMIT n |
~5 s (full sort) |
ORDER BY <col> <dir>, id ASC LIMIT n (compound) |
~5 s (full sort) |
... LIMIT n OFFSET m (deep page) |
grows with m |
The grid appends a stable key tiebreaker in the same direction as the
sort (ORDER BY col ASC, id ASC / col DESC, id DESC). This is deterministic
(equal-value rows page consistently) and index-friendly: a compound
(col, id) index can, in principle, satisfy the whole top-N as a forward index
scan.
Engine status (ElyraSQL 1.4.7): index-backed top-N now works in both
directions, including the compound (col, key) order the grid emits. Measured on
10M rows with a compound (revenue, id) index:
| Query | Cost |
|---|---|
ORDER BY revenue DESC LIMIT 40 |
~55 ms |
ORDER BY revenue ASC LIMIT 40 |
~53 ms |
ORDER BY revenue DESC, id DESC LIMIT 40 |
~53 ms |
ORDER BY revenue ASC, id ASC LIMIT 40 |
~53 ms |
| grid sort via API (whole chain) | ~32–43 ms |
Sorting a 10M-row table by a secondary column is now ~40 ms end-to-end (it was
~6 s). Add a compound (sortColumn, keyColumn) index on columns you sort at
scale so the engine can serve the grid's col <dir>, key <dir> order as an index
top-N.
Note:
key > ?keyset seeks are still full scans on ElyraSQL, so the export streams via a single unbuffered pass (see Export) rather than keyset pagination.
Paging, filtering, grouping and export remain cheap regardless of sort.
Client-side tips
- Give columns a
widthwhen using column virtualization for accurate offsets. - Match
paging.rowHeightto your real row height for correct virtual scrolling. - Use
persistKeyto avoid re-deriving layout on every visit.