欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL Server获取索引创建时间&重建时间&重组时间

程序员文章站 2022-03-28 19:02:10
之前写过一篇博客“SQL Server中是否可以准确获取最后一次索引重建的时间?“,里面主要讲述了三个问题:我们能否找到索引的创建时间?最后一次索引重建(Index Rebuild)的时间? 最后一次索引重组(INDEX REORGANIZE)的时间呢?,当时得出的结论,答案是我们无法准确的找到索引... ......

之前写过一篇博客sql server中是否可以准确获取最后一次索引重建的时间?“,里面主要讲述了三个问题:我们能否找到索引的创建时间?最后一次索引重建(index rebuild)的时间? 最后一次索引重组(index reorganize)的时间呢?,当时得出的结论,答案是我们无法准确的找到索引的创建时间、最后一次索引重组时间,最后一次索引重建的时间。但是最近看到一篇博客sql server – get index creation date然后研究了一下,即使sql server暂时没有一个系统表或dmv视图有保存索引创建的时间,索引重建的时间、索引重组的时间。但是我们可以通过系统跟踪文件获取它们的值,当然也有限制条件并不是所有的索引都能找到这些值。请见下面详细解说:

 

 

 

索引的创建时间

 

索引的创建时间,可以用下面sql获取,但是我们知道跟踪有可能停止或禁用;跟踪文件也可能被覆盖。所以这种方法只能查询最近一段时间的。它有很强的时效性。所以这种方法不能通用。注定其只能作为一种方法参考,而不能通用。

 

 

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值,也无从判断。所以这里能记录准确的时间,但是无法区分索引重建与索引重组。

 

 

 

 

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; 
 

 

 

测试验证如下所示:

 

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 就会遇到下面错误,需要根据实际情况修改脚本。

 

msg 245, level 16, state 1, line 8

conversion failed when converting the varchar value '50.mssqlserver\mssql\log\log_603' to data type int.

 

 

 

参考资料

 

https://sqlconjuror.com/sql-server-get-index-creation-date/