Sql-Server

更正已創建索引和統計資訊的數據庫

  • September 6, 2018

我繼承了一個數據庫,我相信它是 DBA 的受害者,他們遇到了隨機緩慢的操作,為單個查詢執行調整顧問,並盲目地為所述個別案例創建推薦索引和統計資訊,而不考慮對整個數據庫的影響. 我該如何補救這種情況?

我本人不是 DBA,但有興趣正確地做到這一點 -

  • 我應該刪除所有索引和統計資訊並重新開始嗎?
  • 是否有工具可以查看整個 SQL 操作並推薦要刪除、更新或創建的索引和統計資訊。
  • 針對這種情況的任何推薦標準程序,我無法想像我在遇到這種情況時是獨一無二的

我在 SQL Server 2012 上

考慮遵循急救培訓中使用的停止模式。停下來,思考,觀察和計劃。也就是說,不要急於採取行動。首先收集一些資訊,起草行動計劃,然後才開始做事。如果發生電力事故,在切斷電源之前不要觸摸受害者。同樣,不應該在不知道這些索引有什麼用途的情況下開始刪除索引。

系統是否執行良好?你怎麼知道?也就是說,“足夠好”的定義是什麼?

您是否有一組業務規則,例如*“報表 X 必須在 Y 分鐘內準備就緒”“每日 ETL 必須在 0600 之前完成,因為多維數據集更新從 0610 開始”。也許有類似“數據庫備份必須在 0200 完成,因為磁碟到磁帶備份從 0300 開始”之類的內容。請注意,可能有一些臨時規則,例如“CFO 現在需要 $stuff”*,通常根本沒有記錄。

如果您沒有任何業務限制,您需要與您的老闆、其他使用者和業務討論此類限制。

如果你有一套規則,那是個好消息。現在,看看系統目前是否遵守這些限制。

在您了解系統規則之後,進行一些基本的健康檢查可能是一個好主意。Brent Ozar 的sp_Blitz是廣泛使用的免費工具。如果備份處理不當、缺乏最近的完整性檢查、配置問題等等,就會出現警告。

您可以使用以下查詢來找出使用了哪些索引以及只維護了哪些索引:

select object_name(s.object_id) as [object name], 
      i.name as index_name, 
      user_seeks, 
      user_scans, 
      user_lookups, 
      user_updates 
from   sys.dm_db_index_usage_stats s 
      join sys.indexes i 
          on i.object_id = s.object_id 
         and i.index_id = s.index_id 
where  objectproperty(s.object_id,'isusertable') = 1
      and s.database_id = db_id();

通過一次查詢執行對指定索引的每一次單獨查找、掃描、查找或更新都被計為對該索引的使用,並在此視圖中增加相應的計數器。由使用者送出的查詢引起的操作以及由內部生成的查詢引起的操作(例如收集統計資訊的掃描)都會報告資訊。

user_updates計數器指示由對基礎表或視圖的插入、更新或刪除操作引起的索引維護級別。您可以使用此視圖來確定哪些索引僅由您的應用程序輕度使用。您還可以使用該視圖來確定哪些索引會產生維護成本。您可能需要考慮刪除會導致維護成本但不用於查詢或僅不經常用於查詢的索引。

每當啟動 SQL Server (MSSQLSERVER) 服務時,計數器就會被初始化為空。此外,無論何時分離或關閉數據庫(例如,因為 AUTO_CLOSE 設置為 ON),與該數據庫關聯的所有行都將被刪除。

使用索引時,如果索引中不存在行,則會將行添加到 sys.dm_db_index_usage_stats。添加行時,其計數器最初設置為零。

在這裡sys.dm_db_index_usage_stats (Transact-SQL)你可以找到更多解釋。

請記住,indexes您的數據庫中有一些需要強制執行uniqueness ,因此根本不應該觸及它們,您可以通過以下方式找到它們:

select indexname = i.name,
      schemaname = schema_name(schema_id),
      tablename = object_name(o.object_id),
      is_primary_key,
      is_unique
from   sys.indexes i
      join sys.objects o
        on i.object_id = o.object_id
where  (is_primary_key = 1
      or is_unique = 1)
      and objectproperty(o.object_id,'isusertable') = 1
order  by schemaname,
         tablename,
         indexname; 

最後,您的數據庫可以擁有duplicate indexes,因為無法控制它,在這裡您可以找到找到它們的程式碼: Kimberly Tripp 的刪除重複索引

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