Performance
Primentra is built for entities with hundreds of thousands of rows. This page lists what governs response time, and the measured numbers on two reference datasets.
What affects performance
Full-Text Search
Full-Text Search is optional, and it is the single largest factor on a large entity. With it, global search uses CONTAINS() against a word index. Without it, search falls back to LIKE, which scans every value row.
Setup creates two Full-Text indexes when the feature is present: one on EntityRows(Code, Name) and one on EntityValues(TextValue). Below roughly 10,000 rows the difference is not noticeable.
Indexes
The schema ships around 30 permanent indexes. The ones that decide grid speed are on EntityValues:
| Index | Serves |
|---|---|
IX_EntityValues_EntityRowId_Cover | Fetching every value for a page of rows without a key lookup |
IX_EntityValues_AttributeId_DateTimeValue | Date filters and the year/month value list |
IX_EntityValues_AttributeId_DomainValue | Reference column filters and their counts |
IX_EntityValues_AttributeId_IntValue | Whole-number filters and comparisons |
IX_EntityValues_AttributeId_DecimalValue | Decimal filters and comparisons |
EntityRows carries composite indexes on (EntityId, Name), (EntityId, Code), (EntityId, CreatedAt) and (EntityId, ModifiedAt), which is what makes sorting on those columns cheap.
Pagination
The grid never loads a whole entity. GET /api/data/:entityId takes page and pageSize, and the default page is 100 rows. The stored procedure resolves the matching row ids first, pages that list, and only then fetches the values for the page.
Facet queries
The value lists behind the filter chevrons are separate calls — date-facets, domain-facets and value-facets. They run when you open a filter, not when the grid loads, so opening a large entity costs nothing extra.
Each list returns the values actually present with a record count each. The number list is capped at 1,000 values by default, and 5,000 at most. Above the cap the panel says so and hides Select all, because ticking a partial list would quietly exclude the rest of the column.
Filter ordering
When several filters are active, Primentra narrows in stages:
- The first active filter — global search, name or code — selects the matching rows directly. The dataset is never loaded into memory.
- Remaining filters narrow that result set by successive elimination.
- Domain filters are applied last, as exact-match lookups.
Filtering name = "200" and code = "6" on a 525,000-row entity gives ~1,222 rows from Full-Text Search on Name, narrowed by LIKE on Code to ~311 rows, in about 139 ms.
Full-Text Search: with and against
Measured on 525,000 rows and 7.1 million attribute values.
| Operation | Without FTS (LIKE) | With FTS (CONTAINS) |
|---|---|---|
| Global search | ~3,300 ms | ~19 ms |
EntityRows scan | ~190 ms | ~6 ms |
EntityValues scan | ~1,000 ms | ~9 ms |
Search and filter benchmarks (525,000 rows)
| Operation | Response time |
|---|---|
| Global search (FTS) | ~19 ms |
| Single text filter (name or code) | ~88 ms |
| Combined text filters (name + code) | ~139 ms |
| Domain column filter | ~93 ms |
| No filters (first page load) | ~1.3 s |
Date benchmarks (1,000,000 rows)
| Operation | Response time |
|---|---|
| Opening the year/month value list | ~220 ms |
| Applying a month from the list | ~1.5 s |
Date text filter (03-2022) | ~0.9 s |
| Global search for a date | ~3.0 s |
Each ticked month becomes a date range rather than a YEAR() or MONTH() comparison, so the covering index on EntityValues(AttributeId, DateTimeValue) is used instead of being scanned past.
The interface stays responsive throughout. The longest any of these blocks the UI is under 120 ms, and a spinner appears next to the search box while a query runs.
Sizing
- A fresh database allocates about 145 MB before it holds a record.
- Master data costs roughly 1 GB per million records.
- Full-Text Search needs extra disk for its catalog.
- 4 GB RAM is the minimum. Use 8 GB or more above 100,000 rows.
Related
- Install SQL Server — enabling Full-Text Search and verifying it works
- Sorting, Filtering & Search — the filters these numbers measure
- Database Schema — the tables the indexes sit on
- System Requirements — RAM, disk and SQL Server versions
- Health & Monitoring — checking Full-Text Search status from
/api/health