SQL Server中是否可以準確獲取最後一次索引重建的時間?
在SQL Server中,我們能否找到索引的建立時間?最後一次索引重建(Index Rebuild)的時間? 最後一次索引重組(INDEX REORGANIZE)的時間呢? 答案是我們無法準確的找到索引的建立時間、最後一次索引重組時間,最後一次索引重建的時間。 其實就目前SQL Server的各個版本而言,還沒有一個系統表或DMV檢視有儲存索引建立的時間,索引重建的時間、索引重組的時間。但是有些方法可以間接得到最後一次索引重建的時間,但是這個值有時候往往不是準確的(有時候是準確的,有時候是不準確的)。
在sys.sysindexes 中沒有記錄索引的建立、修改時間。而在sys.objects中,有create_date和modify_date兩個欄位,但是sys.objects不會記錄所有索引的相關資訊。所以modify_date的值不能作為用來判斷索引重建、索引重組的時間。這兩個欄位的具體意義如下:
create_datedatetime 物件的建立日期。
modify_datedatetime 上次使用 ALTER 語句修改物件的日期。 如果物件為表或檢視,則建立或修改表或檢視的聚集索引時,modify_date 也會隨之更改。
其實,我們往往可以根據STATS_DATE函式來獲取索引的最後一次重建時間(不準確),STATS_DATE:返回表或索引檢視上統計資訊的最新更新的日期。如下測試所示:
SELECT * INTO TEST FROM sys . objects
CREATE INDEX PK_TEST ON TEST ( object_id );
CREATE INDEX IX_TEST_N1 ON TEST ( name );
如上所示,STATS_DATE獲取索引的統計資訊更新時間,似乎可以作為索引建立的時間。但是我後面就有例子,反證這個是不準確(不靠譜)的。接下來,我們看看,使用 STATS_DATE 來獲取索引重建的時間。如下所示:
ALTER INDEX IX_TEST_N1 ON TEST REBUILD; SELECT name AS Stats , STATS_DATE(object_id, stats_id) AS LastStatsUpdate FROM sys.stats WHERE object_id = OBJECT_ID('dbo.TEST') AND LEFT(name, 4) != '_WA_'; GO
但是更新索引的統計資訊也會引起對應的STATS_DATE的時間變化,此時這個時間就不是索引的最後一次重建時間(Index Rebuild)了。所以使用索引對應統計資訊的最後一次更新時間作為最後一次索引重建的時間,有時候往往不準確。 這個只能作為參考,而不能作為依據。
UPDATE STATISTICS TEST PK_TEST WITH FULLSCAN ;
另外,索引重組(INDEX REORGANIZE)不會引起索引對應統計資訊的更新,所以這個STATS_DATE系統函式不能作為索引重組的時間依據。
ALTER INDEX IX_TEST_N1 ON TEST REORGANIZE ;
最後,我們來看一個例子。如下所示,建立一個空表,我們可以看到,沒有生成相關索引的統計資訊。這種場景下,STATS_DATE函式返回的值為NULL,此時可以看到STATS_DATE 並不能作為索引建立的時間。或者換個說法,這個案例就是一個活生生的反例。
DROP TABLE TEST; CREATE TABLE TEST ( ID INT , NAME VARCHAR(12) , SEX BIT DEFAULT 0 , CONSTRAINT PK_TEST PRIMARY KEY(ID) ); SELECT GETDATE(); CREATE INDEX IX_TEST_N1 ON TEST(NAME, SEX);
參考資料:
https://dba.stackexchange.com/questions/82943/find-out-when-your-index-was-last-rebuilt-reorganized