为什么SELECT FROM sys.dm_db_index_usage_stats返回两行/表?

Tom*_*Tom 2 sql-server

我为什么这样做:

SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE OBJECT_ID=OBJECT_ID('TestTableName') 
Run Code Online (Sandbox Code Playgroud)

我得到两条记录而不是一条记录吗?

我打算使用last_user_update来确定先前调用查询的某些本地缓存数据是否是最新的,或者是否因为表已更改而过期.

last_user_update列在此查询返回的两个记录中都相同.我可以只使用第一条记录中的值,还是可能会有所不同?

请参阅下面的屏幕截图获取结果

屏幕捕获结果

DatabaseName    last_user_update    database_id object_id   index_id    user_seeks  user_scans  user_lookups    user_updates    last_user_seek  last_user_scan  last_user_lookup    last_user_update    system_seeks    system_scans    system_lookups  system_updates  last_system_seek    last_system_scan    last_system_lookup  last_system_update
TestTableName 2016-04-27 07:53:51.740   5   939150391   1   0   101556  101557  6   NULL    2016-04-28 07:27:17.933 2016-04-28 07:27:17.927 2016-04-27 07:53:51.740 0   3   0   0   NULL    2016-04-27 07:52:49.203 NULL    NULL
TestTableName   2016-04-27 07:53:51.740 5   939150391   2   101559  3   0   6   2016-04-28 07:27:17.927 2016-04-26 17:31:21.200 NULL    2016-04-27 07:53:51.740 0   1   0   0   NULL    2016-04-27 18:21:53.977 NULL    NULL
Run Code Online (Sandbox Code Playgroud)

Mar*_*ith 5

indexid为1表示聚簇索引.

indexid为2是非聚集索引.

如果表的结构为堆(没有聚簇索引),您可能还会看到indexid为0,这实际上不是索引,但无论如何都会在此视图中显示针对它的操作.

关于您的第二个问题,非聚集索引是否涵盖了您感兴趣的所有列?如果您只关心是否更新了任何列,您也可以只查看聚簇索引的行,因为任何更新都不可能影响NCI而不影响CI.

您可能会因为您的方法而得到误报,因为此列仅显示执行执行计划的最后一次,其中包含可以更新此索引的运算符,而不是确实发生了更新.服务重新启动或数据库设置为脱机后,值也将为null(自动关闭时可能会发生).

  • @TheGameiswar谢谢.关于这方面的更多细节BTW https://blogs.msdn.microsoft.com/craigfr/2008/10/30/what-is-the-difference-between-sys-dm_db_index_usage_stats-and-sys-dm_db_index_operational_stats/ (2认同)