在SQL Server中,我們能否找到索引的創建時間?最後一次索引重建(Index Rebuild)的時間? 最後一次索引重組(INDEX REORGANIZE)的時間呢? 答案是我們無法準確的找到索引的創建時間、最後一次索引重組時間,最後一次索引重建的時間。 其實就目前SQL Server的各個版... ...
在SQL Server中,我們能否找到索引的創建時間?最後一次索引重建(Index Rebuild)的時間? 最後一次索引重組(INDEX REORGANIZE)的時間呢? 答案是我們無法準確的找到索引的創建時間、最後一次索引重組時間,最後一次索引重建的時間。 其實就目前SQL Server的各個版本而言,還沒有一個系統表或DMV視圖有保存索引創建的時間,索引重建的時間、索引重組的時間。但是有些方法可以間接得到最後一次索引重建的時間,但是這個值有時候往往不是準確的(有時候是準確的,有時候是不准確的)。
在sys.sysindexes 中沒有記錄索引的創建、修改時間。而在sys.objects中,有create_date和modify_date兩個欄位,但是sys.objects不會記錄所有索引的相關信息。所以modify_date的值不能作為用來判斷索引重建、索引重組的時間。這兩個欄位的具體意義如下:
create_date datetime 對象的創建日期。
modify_date datetime 上次使用 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