How to Manage Database Index Usage and Cost per Company in Microsoft Dynamics 365 Business Central (2026 Release Wave 1)
Introduction
Microsoft Dynamics 365 Business Central 2026 release wave 1 (version 28) introduces a built-in way to view and manage database indexes on a per-company basis, directly from the client. Indexes make reads fast, but they are not free: every index consumes storage and adds work to each insert, update, and delete on the table. Until now, trimming unused indexes was a developer task. With this feature, an administrator can inspect index storage and usage in the UI and selectively turn off non-essential indexes for a single company or across the whole environment, to reduce storage cost and improve write performance.
This post is a hybrid walkthrough. It covers the administrator workflow, the AL developer angle (shipping an index disabled and enabling it only where it is needed), and, most importantly, a decision method so you turn off the right indexes rather than guessing.
Note: The shipped (general availability) build uses the Table Data Management page with Turn index off / Turn index on actions. Earlier public-preview screenshots in the community show an “Enabled in Database” checkbox, that UI changed before release. The steps below follow the GA behaviour.
Business Value
- Lower storage cost by removing the overhead of low-value indexes, especially on large, heavily-transacted tables.
- Faster writes – fewer indexes to maintain means quicker insert, update, and delete operations.
- Per-company precision – disable an index only in the companies where it is not needed, without affecting the rest of the environment.
- Multi-company targeting – ship an index disabled by default and enable it only for the companies or functional areas that actually use it.
- No code change required for an administrator to act; the developer keeps control over the index definition.
Prerequisites
- Microsoft Dynamics 365 Business Central 2026 release wave 1 (v28.0) or later – online (Azure SQL) or on-premises (SQL Server).
- Administrator permissions sufficient to open the Table Information / Table Data Management pages.
- For the AL section: Visual Studio Code with the AL Language extension, using a per-tenant extension object range (this project uses 50100–99999).
- A sandbox environment to test changes before applying them in production.
Requirement
How do I see which indexes a table actually uses in a given company, decide which ones are safe to disable, and turn them off (and back on) without breaking functionality?
Background: Why Indexes Have a Cost
An index is a database structure that lets SQL Server (on-premises) or Azure SQL (online) seek directly to the rows you need instead of scanning the whole table. That is dramatically faster for reads on large tables. The trade-off is that every index takes storage and must be kept up to date on each create, update, and delete, which slows down write operations.
In AL, indexes come from keys. The first key on a table object is the primary key; every key after it (and every key in a table extension) is a secondary key, and each secondary key becomes an index in SQL. This is why the right number of keys is always a compromise between fast retrieval and fast data entry.
Some indexes are protected and cannot be turned off: unique indexes, primary keys, SIFT indexes, and the $systemid index. You can only disable non-unique indexes.
One more concept makes this feature powerful. Tables in Business Central are either per-company (for example, Item or the ledger tables) or shared across companies (for example, Tenant Media). For a per-company table, a complete SQL table definition – including its indexes – exists separately for each company. That is exactly what lets you manage an index independently per company.
The Diagnostic Toolkit: Decide Before You Disable
Do not disable an index just because it looks idle in one screen. Confirm there is a real problem and that the index is genuinely unused, by reading three pages together (Search / Tell Me to open each):
1. Table Information → Table Data Management – per-index storage size, usage statistics, and index type (AL-defined or system-generated) for the selected company. This is where you act.
2. Database Missing Indexes – the columns SQL thinks you should add. Check this so you do not disable an index the database is, in effect, asking for, and to keep a balanced picture of read vs. write needs.
3. Database Wait Statistics – take a baseline snapshot, let users work for a representative period, then take a second snapshot. The delta tells you what the database was actually waiting on. If write/I-O overhead is not a real bottleneck, you may not need to disable anything.
A safe candidate to turn off is typically an index that is non-unique, shows low or zero read activity (seeks, scans, lookups) relative to a high update count, occupies meaningful storage, and is not surfaced as needed in Database Missing Indexes. Because usage counters reset when the database restarts, judge them over a representative window, not a single morning.
Part A – Administrator Walkthrough
Step 1: Open Table Information
Choose the Search (Tell Me) icon (Alt+Q) in the upper-right corner, enter “Table Information”, and choose the related link.
Step 2: Open the table and select the company
On the Table Information page, find the table you want to analyze and select its ID in the Table No. column. This opens the Table Data Management page. Set the Company Name field to the company whose indexes you want to inspect. If Company Name is empty, the table is shared by all companies.
Step 3: Read the Indexes section
The Indexes section lists each index on the table for the selected company, with its storage size, usage statistics, and index type (AL-defined or system-generated). Use these values to spot underused indexes in that specific company or environment.
Under the hood, this data comes from a virtual table called Database Index, which surfaces the SQL dynamic management view sys.dm_db_index_usage_stats. That DMV tracks read activity (seeks, scans, lookups) versus writes (updates), and the virtual table exposes two metric sets – user* and last_user* – so you can see both how often and how recently an index was used.
Step 4: Apply the decision method
Before turning anything off, cross-check the candidate against Database Missing Indexes and Database Wait Statistics, as described in the Diagnostic Toolkit above. Confirm the index is non-unique, lightly read, frequently written, and meaningfully large.
Step 5: Turn the index off
On the Table Data Management page, select the index in the list, then choose one of:
- Turn index off – disables the index for the selected company only.
- Turn index off (all companies) – disables the index for every company in the environment.
Disabling an index takes effect immediately.
Step 6: Turn the index back on
Select the disabled index in the list, then choose Turn index on (this company) or Turn index on (all companies).
Be aware of the asymmetry: enabling an index is queued for the next scheduled midnight process, not applied instantly. Re-enabling also forces SQL to scan the whole table to rebuild the index, which can take time on large tables. Factor this into any maintenance or troubleshooting plan where you may need an index back quickly.
Step 7: Measure before and after
Treat this as a measured change, not a one-way switch. Note the index storage size before you disable it, and take a Database Wait Statistics snapshot. After the change has been live for a representative period, compare the storage reclaimed and the wait-statistics delta to confirm the write/storage improvement was real – and that you did not introduce read regressions.
Part B – The AL Developer Angle
Step 8: Remember that keys are indexes
Every secondary key you define becomes a SQL index. The key’s Enabled property controls whether that index is actually maintained on SQL Server. An enabled secondary key costs storage and write time; a disabled one does not, but it is unavailable for sorting and seeking until you re-enable it.
Step 9: Ship a key disabled by default
If a key only benefits a specific scenario, you can ship it disabled so it costs nothing until someone needs it. Set Enabled = false in the key definition:
| tableextension 50100 “MyPrefix Cust. Ledger Entry Ext” extends “Cust. Ledger Entry” { keys { // Shipped disabled – no storage or write cost until enabled. key(MyPrefix_PostingDateSource; “Posting Date”, “Source Code”) { Enabled = false; // Cover frequent columns so the index can answer more queries. IncludedFields = “Document No.”, Amount; } } } |
Replace MyPrefix with your registered object/affix and keep the object ID in your assigned range. IncludedFields (non-key “included columns”) let the index cover more queries without widening the key itself.
Step 10: Enable per company for a multi-company strategy
Because each company holds its own copy of a per-company table’s index definitions, you can ship a key with Enabled = false and then turn it on only in the companies that need it – using the Turn index on action on the Table Data Management page. This is ideal for an index that only matters to a functional area used by a subset of companies: the companies that use it get the read performance, while the rest avoid the storage and write overhead entirely.
The same applies in reverse for administrators: an index that ships enabled can be turned off in the specific companies where it is not pulling its weight, without a code change and without touching other companies.
Important Notes
- Protected indexes – unique indexes, primary keys, SIFT, and $systemid cannot be turned off. Only non-unique indexes are eligible.
- Disabling is immediate; enabling is deferred to the next scheduled midnight process and rebuilds the index by scanning the whole table. Plan maintenance windows accordingly.
- Mind the scope: “Turn index off” affects only the selected company, while “Turn index off (all companies)” affects the whole environment.
- The feature applies to both online (Azure SQL) and on-premises (SQL Server) deployments.
- Do not disable indexes relied on by reports, queries, list filtering, or integrations. Usage counters reset on database restart, so evaluate them over a representative period before deciding.
- Be conservative with financial-integrity tables (ledgers) and always test in a sandbox first – re-enabling a large index can be time-consuming, and read regressions can be subtle.
Conclusion
Managing database index usage per company puts a previously developer-only lever into the hands of administrators, while still giving developers fine-grained control through the Enabled property. The real value is not the on/off switch itself but the workflow around it: read the Database Index, Missing Indexes, and Wait Statistics pages together, disable only well-justified non-unique indexes, and measure the result. Used this way, the feature is a precise tool for cutting storage cost and improving write performance – company by company – without sacrificing the reads your users depend on.