You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sp_IndexCleanup: base the unused-index window on each database's restore or create time, not only server uptime #907
The low-uptime guard reads the server's start time from sys.dm_os_sys_info. At 7 days or less it switches to @dedupe_only, and under 14 days it adds a warning to each Unused Index row.
Index usage also starts over when a database is restored or created, but the guard does not look at that. On a test server that had been up for weeks, with a database restored a week earlier, the proc reported 380 to 501 indexes per database as unused with no warning. On an AG primary, reads on the readable secondaries are not counted either, and nothing says so.
Steps to Reproduce
Use a server that has been up for more than 14 days.
Restore a database, or create one, and use it only lightly.
Run EXECUTE dbo.sp_IndexCleanup @database_name = N'<that database>'; in default mode.
Expected Behavior
The output shows that this database's usage only covers the days since its restore, warns on its Unused rows, and skips the unused rule if that is 7 days or less.
Actual Behavior
Every index the light use did not touch is an Unused Index row with a DISABLE script, and there is no warning, because the server uptime is over 14 days.
Additional Context
Suggested change. The display matters most with @get_all_databases = 1, so this keeps the information to one place per database:
Add two columns to the existing DATABASE level row of the summary: usage_since and usage_since_reason. The value is the latest of the server start, the database's last restore (msdb.dbo.restorehistory) and its create_date. The reason names which one it was. Table rows leave both blank.
Base the existing "Unused Index (WARNING: ...)" label on that database's own window instead of server uptime. When a database has been around as long as the server has been up, no row changes.
Make the automatic switch to dedupe-only per database. A database restored 3 days ago skips the unused rule, and its DATABASE row says so. Other databases in the same run are judged normally.
On an AG primary with readable secondaries, add a note to the DATABASE row that reads on the secondaries are not counted.
Keep the server uptime in the header row and the ANALYZED OBJECT DETAILS row, where it is now.
Fixed in #925, merged to dev as cfc0bcb. Each database now has its own usage window: the latest of server start, its last restore (msdb.dbo.restorehistory) and its create_date.
The DATABASE row shows usage_since and usage_since_reason.
The Unused Index warning follows that window. A database whose window is the server start gets the same label as before.
A database with 7 days of usage data or less skips the unused index rule, and its DATABASE row says so. Other databases in the same run are judged normally.
On an AG primary with readable secondaries, the reason notes that reads on the secondaries are not counted. This path has not been run: no test server has an AG.
Per-day rates on TABLE rows divide by the database window.
The README update for the uptime guard ships with the release. The text is in the PR description.
Activity
Merge pull request #925 from erikdarlingdata/fix/907-usage-window
erikdarlingdata commentedon Oct 24, 2026
Claude posting for Erik Darling.
Fixed in #925, merged to dev as cfc0bcb. Each database now has its own usage window: the latest of server start, its last restore (msdb.dbo.restorehistory) and its create_date.
usage_sinceandusage_since_reason.The README update for the uptime guard ships with the release. The text is in the PR description.