Question: When did a user last access a table? Index-usage statistics report the latest recorded user seeks, scans, lookups and updates. They provide recent diagnostic history, not a permanent access audit.

During a Comprehensive Database Performance Health Check, customers often tell me which tables they consider important or lightly used. I value that knowledge from developers and DBAs. This report helps us compare it with the activity SQL Server has recorded.
SELECT DB_NAME() AS database_name,
s.name AS schema_name, t.name AS table_name,
MAX(ius.last_user_lookup) AS last_user_lookup,
MAX(ius.last_user_scan) AS last_user_scan,
MAX(ius.last_user_seek) AS last_user_seek,
MAX(ius.last_user_update) AS last_user_update
FROM sys.tables AS t
JOIN sys.schemas AS s ON s.schema_id = t.schema_id
LEFT JOIN sys.dm_db_index_usage_stats AS ius
ON ius.database_id = DB_ID() AND ius.object_id = t.object_id
GROUP BY s.name, t.name
ORDER BY s.name, t.name;The report includes schema names and all user tables in the current database, even those with no matching usage row. It aggregates the latest timestamp across the table’s reported indexes. The update column has its own correct name; it isn’t another seek timestamp.
NULL means there is no corresponding recorded timestamp in this observation history. It does not prove the table is unused. The engine clears counters on restart, and database shutdown or detach can also remove entries. Memory-optimized and spatial index use is outside this DMV’s coverage.
Check the engine’s startup time and ask whether the observation period included month-end, scheduled jobs and other infrequent work. A table that supports a monthly task can look idle on an ordinary Tuesday.
These timestamps don’t identify the person who ran a query. “User” separates user-submitted work from internal system operations. Use appropriate auditing if you need a durable record of who accessed what.
I use this as a conversation starter before index changes, not as permission to drop a table or index. SQL Server 2022 and later require VIEW SERVER PERFORMANCE STATE; earlier versions require VIEW SERVER STATE.
Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.
Discover more from SQL Authority with Pinal Dave
Subscribe to get the latest posts sent to your email.





8 Comments. Leave new
I am lucky that we restart the servers once a month so I use your method to tell me both what tables get used and how every month. Actually got this from Tim Ford.
Typo: MAX(ius.[last_user_update]) AS [last_user_seek]
Hi Pinal,
Very helpful query.
But is returning just the tables on dbo schema, there is some way to get the tables stats on each schema ?
Best regards,
Andres
Andres,
What Pinal is doing is using the fact that once a table/index is accessed it will show up in sys.dm_db_index_usage_stats. It shouldn’t matter what the schema is.
HTH
Chris
Thank you Chris ( my mistake ).
Is showing the tables in any schema.
Is there something similar that tells the last time a procedure or function was executed?
Great query! Is there something similar that identifies the last time a procedure or function is called?
Hi Dave- Great info but would it possible to add the login or host name as well to this script?