Sql-Server

辨識 SQL Azure 上未使用的索引

  • December 1, 2020

我有一個大型 SQL Azure 數據庫(P6 接近 1TB)。我想清理/刪除任何未使用的索引。在過去的 30 天裡,我們擷取了以下 2 組資訊。

見:https ://gist.github.com/eoincampbell/3fe775d43e86ad342f9c6eba10f350f9

  • sys.dm_db_index_physical_stats從join to收集的 Index sys.tablesStatssys.schemassys.indexes
  • 索引使用情況收集自sys.dm_db_index_usage_stats

我對sys.dm_db_index_usage_stats. 從文件中不清楚何時/是否在 SQL Azure 環境中發生以下情況(與單實例 MSSQLServer 相比。)

https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-db-index-usage-stats-transact-sql?view=azuresqldb-current _每當 SQL Server (MSSQLSERVER) 服務啟動時,計數器就會被初始化為空。此外,無論何時分離或關閉數據庫(例如,因為 AUTO_CLOSE 設置為 ON),與該數據庫關聯的所有行都將被刪除。

這是我用來隨後辨識未使用索引的查詢。它

  1. 獲取數據庫中所有索引的最新索引資訊(812條記錄)
  2. 獲取所有索引的最新使用資訊(558 條記錄)
  3. LEFT OUTER 將它們連接在一起
  4. 排除任何聚集/PK 索引
  5. 返回沒有使用統計資訊的任何內容或任何使用者讀取統計資訊為零的內容。

返回的總行數約為 219 行

這種方法看起來有效嗎?

詢問


WITH MostRecentStats (
   SchemaName, TableName, IndexName, IndexType, AllocUnitType, Pages, MostRecentAt
)
AS (
   SELECT      SchemaName, TableName, IndexName
               , IndexTypeDescription, AllocUnitTypeDescription
               , Max(PageCount) , Max(RecordDate)
   FROM        DBStats.IndexStats
   GROUP BY    SchemaName, TableName, IndexName
               , IndexTypeDescription, AllocUnitTypeDescription
   -- ****** Returns 812 Indexes across all tables ******
)
, AllCombinedUsage (
   SchemaName, TableName, IndexName
   ,user_seeks, user_scans, user_lookups, user_updates 
   , system_seeks, system_scans, system_lookups, system_updates
)
AS (
   SELECT      SchemaName, TableName, IndexName
               , sum(user_seeks), sum(user_scans), sum(user_lookups), sum(user_updates)    
               , sum(system_seeks), sum(system_scans), sum(system_lookups), sum(system_updates)
   FROM        DBStats.IndexUsage
   GROUP BY    SchemaName, TableName, IndexName
   -- Only Returns 558 Index with Usage Statistics... 
)
SELECT      a.SchemaName, a.TableName, a.IndexName, a.Pages
           , b.*
FROM        MostRecentStats a
LEFT JOIN   AllCombinedUsage b
           ON a.SchemaName = b.SchemaName 
           AND a.TableName = b.TableName
           AND a.IndexName = b.IndexName
WHERE       a.IndexName NOT LIKE 'PK_%' --Filter out all Primary Keys
AND         a.IndexType <> 'CLUSTERED INDEX' --And Clusted Indexes
AND (
           b.IndexName IS NULL --Include everything that has no index usage data
           OR
           (b.user_seeks + b.user_scans + b.user_lookups) = 0
           --Include everything with 0 User Reads on the data
)
ORDER BY    a.Pages DESC

Azure SQL 數據庫的問題在於,您無法控制何時重新啟動 SQL Server 或您的數據庫轉移到不同的實例 - 即,索引使用集合可能來自比可用時間短得多的時間跨度為你。

一種選擇是使用 Azure SQL 數據庫中內置的自動索引管理功能。

另一種選擇是讓您將 sys.dm_dm_index_usage_stats 中的資訊具體化到您自己的表中,以便資訊在這些東西中保留下來。我沒有尋找這樣的腳本,但可能已經存在“外面”的東西。

一個有趣的因素是重新啟動 SQL Server 的時間:

SELECT sqlserver_start_time  
FROM sys.dm_os_sys_info;  

不過,我不能確定這是否包括所有使用統計數據將被擦除的情況。

下面是幾篇關於該主題的文章,它們添加了一些資訊: https ://www.c-sharpcorner.com/article/dropping-unused-indexes-on-an-azure-sql-database/ https://sqlperformance。 com/2018/04/azure/automatic-index-management-in-azure-sql-database

您可能還需要排除唯一索引

引用自:https://dba.stackexchange.com/questions/280647