以前写过一篇博客“SQL Server中是否能够准确获取最后一次索引重建的时间?“,里面主要讲述了三个问题:咱们可否找到索引的建立时间?最后一次索引重建(Index Rebuild)的时间? 最后一次索引重组(INDEX REORGANIZE)的时间呢?,当时得出的结论,答案是咱们没法准确的找到索引的建立时间、最后一次索引重组时间,最后一次索引重建的时间。可是最近看到一篇博客“SQL Server – Get Index Creation Date”,而后研究了一下,即便SQL Server暂时没有一个系统表或DMV视图有保存索引建立的时间,索引重建的时间、索引重组的时间。可是咱们能够经过系统跟踪文件获取它们的值,固然也有限制条件,并非全部的索引都能找到这些值。请见下面详细解说:html
索引的建立时间sql
索引的建立时间,能够用下面SQL获取,可是咱们知道跟踪有可能中止或禁用;跟踪文件也可能被覆盖。因此这种方法只能查询最近一段时间的。它有很强的时效性。因此这种方法不能通用。注定其只能做为一种方法参考,而不能通用。app
DECLARE @filename VARCHAR(500)
SELECT @filename = CAST(value AS VARCHAR(500))
FROM fn_trace_getinfo(DEFAULT)
WHERE property = 2
AND value IS NOT NULL
-- Go back 4 files since default trace only keeps the last 5 and start from there.
SELECT @filename = substring(@filename, 0, charindex('_', @filename)+1) + convert(varchar, (convert(int, substring(left(@filename, len(@filename)-4), charindex('_', @filename)+1, len(@filename)))-4)) + '.trc'
SELECT
gt.EventClass,
gt.EventSubClass,
te.Name AS EventName,
gt.HostName,
gt.StartTime,
gt.DatabaseName,
gt.ObjectName,
gt.IndexID
FROM fn_trace_gettable(@fileName, DEFAULT) gt
JOIN sys.trace_events te ON gt.EventClass = te.trace_event_id
WHERE EventClass = 46
and ObjectType = 22601
and gt.DatabaseName <> 'tempdb'
ORDER BY StartTime desc;
索引的重建时间 &索引的重组时间测试
以下所示,Object:Altered的trace_event_id为164,这里咱们没法区分ALTER INDEX ... REBUILD 和 ALETER INDEX ...REORGANIZE. 对于索引重建、索引重组,fn_trace_gettable返回的TextData为Null值,也无从判断。因此这里能记录准确的时间,可是没法区分索引重建与索引重组。ui
DECLARE @filename VARCHAR(500)
SELECT @filename = CAST(value AS VARCHAR(500))
FROM fn_trace_getinfo(DEFAULT)
WHERE property = 2
AND value IS NOT NULL
-- Go back 4 files since default trace only keeps the last 5 and start from there.
SELECT @filename = substring(@filename, 0, charindex('_', @filename)+1) + convert(varchar, (convert(int, substring(left(@filename, len(@filename)-4), charindex('_', @filename)+1, len(@filename)))-4)) + '.trc'
SELECT
gt.EventClass,
gt.EventSubClass,
te.Name AS EventName,
gt.HostName,
gt.StartTime,
gt.DatabaseName,
gt.ObjectName,
gt.IndexID
FROM fn_trace_gettable(@fileName, DEFAULT) gt
JOIN sys.trace_events te ON gt.EventClass = te.trace_event_id
WHERE EventClass = 164
and ObjectType = 22601
and gt.DatabaseName <> 'tempdb'
ORDER BY StartTime desc;
测试验证以下所示:spa
USE YourSQLDba;
GO
ALTER INDEX Pk_HistMaintTrav ON [Maint].[JobHistory] REBUILD;
ALTER INDEX PK_DataBaseSizeDtl_Day ON [Maint].[DataBaseSizeDtl_Day] REORGANIZE;
CREATE INDEX IX_DataBaseSizeDtl_Day_N1 ON [Maint].[DataBaseSizeDtl_Day](DataBaseName);
注意:上面脚本在有些环境可能会出错,主要是由于trac文件的路径,例如C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Log\log_603.trc 就会遇到下面错误,须要根据实际状况修改脚本。code
Msg 245, Level 16, State 1, Line 8orm
Conversion failed when converting the varchar value '50.MSSQLSERVER\MSSQL\Log\log_603' to data type int.server
参考资料:htm
https://sqlconjuror.com/sql-server-get-index-creation-date/