Grid Performance at Scale
Grid Performance at Scale
~9 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026
A grid with a hundred test rows always feels fast - a testimonial management area with thousands of entries (multiple languages, years of collected testimonials) is where the real bottlenecks show up. This chapter walks through the most common performance levers.
Indexes on filtered/sorted columns
Every column that's regularly filtered or sorted in the grid should get a matching index in db_schema.xml - without an index, MySQL scans the entire table on every filter:
<index referenceId="MIRONSOFT_TESTIMONIAL_IS_ACTIVE" indexType="btree">
<column name="is_active"/>
</index>
<index referenceId="MIRONSOFT_TESTIMONIAL_POSITION" indexType="btree">
<column name="position"/>
</index>After a change to db_schema.xml, the rule from chapter 2 applies again: setup:upgrade is mandatory, or the index only exists on paper.
Hiding columns you don't need
Every extra column means extra data per row traveling over the wire to the browser. Rarely used columns (for example created_at in an overview that mainly filters by status) can be hidden by default with <visible>false</visible> without removing them entirely - editors can still show them via columnsControls (chapter 7) when needed.
Avoiding N+1 queries in custom column renderers
Achtung: A common, hard-to-spot performance mistake: a custom column class (like Rating from chapter 19) that runs an extra database query or service call per row inside prepareDataSource(). Unnoticed at 20 rows, a noticeable load-time jump at 500 rows. Extra data for the whole page should instead be loaded once up front (for example in getData() on the DataProvider, chapter 5) and only looked up per row afterward.
Full-text search and LIKE queries
The text filter from chapter 7 uses LIKE %value% - a leading percent sign fundamentally prevents using a B-tree index for that column, because MySQL can't compare left-to-right through the index. For very large tables with frequent full-text search, a dedicated FULLTEXT index (via db_schema.xml as indexType="fulltext") is a significantly faster alternative, though with different search semantics (word boundaries instead of substrings).
Using pagination correctly
The default pagination (chapter 4) already correctly limits the database query via LIMIT/OFFSET - the real performance risk rarely lives here, but rather in custom code that accidentally operates on the full collection before pagination (for example a PHP loop in getData() that goes beyond parent::getData() before LIMIT has been applied).
Checklist for large grids
- Index every frequently filtered/sorted column in
db_schema.xml. - Hide rarely needed columns by default (
visible: false) instead of removing them. - No per-row database queries in column renderers - preload once instead.
- For heavy full-text search, consider a
FULLTEXTindex instead ofLIKE %...%. - Always run custom
getData()logic after, not before, pagination.