SQL Server中如何識別、查找未使用的索引(unused indexes)

来源:https://www.cnblogs.com/kerrycode/archive/2018/05/22/9074694.html
-Advertisement-
Play Games

在SQL Server中,索引是優化SQL性能的一大法寶。但是由於各種原因,索引會被當做“銀彈”濫用,一方面有些開發人員(甚至是部分資料庫管理員)有一些陋習,不管三七二十一,總是根據所謂的"感覺"或“經驗”先增加一些索引,而不管這些索引是否未被使用或是否合理。另外一方面在資料庫的生命周期中,需求總是... ...


 

在SQL Server中,索引是優化SQL性能的一大法寶。但是由於各種原因,索引會被當做銀彈濫用,一方面有些開發人員(甚至是部分資料庫管理員)有一些陋習,不管三七二十一,總是根據所謂的"感覺"或經驗先增加一些索引,而不管這些索引是否未被使用或是否合理。另外一方面在資料庫的生命周期中,需求總是在變化,業務也在變化,有些當初創建的有效索引可能已經變成了unused index了。變成了資料庫性能的累贅; 另外,部分資料庫管理員其實很少清理索引(冗餘索引,重覆索引,未使用索引)。其實不管是出於性能考慮,還是資料庫維護管理的需要,資料庫中的未使用索引(unused index)都需要定期清理,因為這些未使用索引(unused index)不但不會提高查詢性能,還會影響DML操作的性能、浪費存儲空間等等。本文主要總結一下,如何找到識別、查找哪些未使用的索引(unused index)

 

 

   如何找到未使用索引呢? 在ORACLE資料庫中提供了監控索引使用情況的功能。雖然在SQL Server中沒有提供此類功能,但是提供了DMV視圖sys.dm_db_index_usage_stats ,關於這個視圖,詳細信息可以參考官方文檔,下麵僅僅介紹需要用到的幾個欄位

 

user_scans      用戶查詢執行的掃描次數。

user_seeks      用戶查詢執行的搜索次數。

user_lookups    用戶查詢執行的書簽查找次數。

user_updates    通過用戶查詢執行的更新次數。這表示插入、 刪除,更新的次數,而不是受影響的實際行數。

                例如,如果你刪除在一個語句中的 1000行,此計數遞增 1

                Number of updates by user queries. This includes Insert, Delete, and Updates representing

                number of operations done not the actual rows affected. For example, if you delete 1000

                rows in one statement, this count increments by 1

 

我們可以使用下麵SQL語句查找當前資料庫中的未使用索引(unused index):

 

SELECT 'SQL Server Instance Start with ' + CONVERT(VARCHAR(16),create_date,120)  FROM sys.databases
WHERE database_id =2;
    
SELECT  DB_NAME(diu.database_id)                  AS DatabaseName ,
        s.name +'.' +QUOTENAME(o.name)            AS TableName    ,
        i.index_id                                AS IndexID   ,
        i.name                                    AS IndexName        ,
        CASE WHEN i.is_unique =1 THEN 'UNIQUE INDEX'
           ELSE 'NOT UNIQUE INDEX'    END         AS IS_UNIQUE,
        CASE WHEN i.is_disabled=1 THEN 'DISABLE'
           ELSE 'ENABLE'            END           AS IndexStatus,
        o.create_date                             AS IndexCreated,
        STATS_DATE(o.object_id,i.index_id)        AS StatisticsUpdateDate,
        diu.user_seeks                            AS UserSeek ,
        diu.user_scans                            AS UserScans ,
        diu.user_lookups                          AS UserLookups ,
        diu.user_updates                          AS UserUpdates ,
        p.TableRows ,
        'DROP INDEX ' + QUOTENAME(i.name) 
        + ' ON ' + QUOTENAME(s.name) + '.'
        + QUOTENAME(OBJECT_NAME(diu.object_id)) +';' AS 'Drop Index Statement'
FROM    sys.dm_db_index_usage_stats diu
        INNER JOIN sys.indexes i ON i.index_id = diu.index_id
                                    AND diu.object_id = i.object_id
        INNER JOIN sys.objects o ON diu.object_id = o.object_id
        INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
        INNER JOIN ( SELECT SUM(p.rows) TableRows ,
                            p.index_id ,
                            p.object_id
                     FROM   sys.partitions p
                     GROUP BY p.index_id ,
                            p.object_id
                   ) p ON p.index_id = diu.index_id
                          AND diu.object_id = p.object_id
WHERE   OBJECTPROPERTY(diu.object_id, 'IsUserTable') = 1
        AND diu.database_id = DB_ID()
        AND i.is_primary_key = 0        --排除主鍵索引
        AND i.is_unique_constraint = 0         --排除唯一索引
        AND diu.user_updates <> 0              --排除沒有數據變化的索引
        AND diu.user_lookups = 0
        AND diu.user_seeks = 0
        AND diu.user_scans = 0
        AND i.name IS NOT NULL                 --排除那些沒有任何索引的堆表
ORDER BY ( diu.user_seeks + diu.user_scans + diu.user_lookups ) ASC,diu.user_updates DESC;
GO

 

 

需要註意的幾點:

 

1:sys.dm_db_index_usage_stats返回索引的被使用的信息,但是這個DMV視圖中的數據是自資料庫服務啟動以來累計收集的數據(只要重啟SQL Server服務,該視圖的計數器就初始化為空。 而且,當分離或關閉資料庫時(例如,由於 AUTO_CLOSE 設置為 ON),便會刪除與該資料庫關聯的所有記錄。),所以,如果資料庫只運行了幾天,那麼這個視圖的數據有可能不是特別準確(例如,有些OLAP的批處理或作業,一個月才運行一次)。所以在判斷分析前,一定要查看資料庫服務已經運行多長時間了。一般合適的時間是一個月以上,最好是兩個月以上。

 

2:sys.dm_db_index_usage_stats不返回有關記憶體列存儲索引的信息

 

3:註意欄位IndexCreated,如果索引是最近幾天創建的,也要謹慎分析,不要急於刪除。

 

4:註意條件裡面有些欄位過濾條件,其實都是包含一定業務意義的。

 

 

另外,上面腳本只能查詢當前資料庫的未使用索引,如果需要查詢當前實例下的所有資料庫,那麼可以使用下麵腳本

 

 

EXEC sp_MSforeachdb 'USE [?] ; 
SELECT  DB_NAME(diu.database_id)                  AS DatabaseName ,
        s.name +''.'' +QUOTENAME(o.name)          AS TableName    ,
        i.index_id                                AS IndexID        ,
        i.name                                    AS IndexName    ,
        CASE WHEN i.is_unique =1 THEN ''UNIQUE INDEX''
           ELSE ''NOT UNIQUE INDEX''    END       AS IS_UNIQUE,
        CASE WHEN i.is_disabled=1 THEN ''DISABLE''
           ELSE ''ENABLE''            END         AS IndexStatus,
        o.create_date                             AS IndexCreated,
        STATS_DATE(o.object_id,i.index_id)        AS StatisticsUpdateDate,
        diu.user_seeks                            AS UserSeek ,
        diu.user_scans                            AS UserScans ,
        diu.user_lookups                          AS UserLookups ,
        diu.user_updates                          AS UserUpdates ,
        p.TableRows ,
        ''DROP INDEX '' + QUOTENAME(i.name) 
        + '' ON '' + QUOTENAME(s.name) + ''.''
        + QUOTENAME(OBJECT_NAME(diu.object_id)) +'';'' AS ''Drop Index Statement''
FROM    sys.dm_db_index_usage_stats diu
	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Nginx使用Location匹配URL進行偽靜態,location [ = | ~ | ~* | ^~ ] uri { ... }中=、~、~*、^*、^~等的區別。 ...
  • 本文配置可實現:集群伺服器之間相互可以ssh免密登錄。若只想從單一機器(如master)ssh免密登錄其他機器(slave1、slave2),則只跟著操作到第二步即可。 建議先花兩三分鐘把全文看完再跟著步驟操作 操作步驟: 1.集群環境:master、slave1和slave2;操作系統為Cento ...
  • 一、安裝與配置 1.設置阿裡雲鏡像源 2.安裝依賴包 3.安裝 Docker CE 重建 Yum 緩存。 安裝 Docker CE ,請執行一下命令進行安裝: 4.啟動 Docker CE 5. [可選] 為 Docker 建立用戶組 docker 命令與 Docker 引擎通訊之間通過 UnixS ...
  • sed 字元串替換 1. sed替換的基本語法為: sed 's/原字元串/替換字元串/' 單引號裡面,s表示替換,三根斜線中間是替換的樣式,特殊字元需要使用反斜線”\”進行轉義。 2. 單引號” ‘ ’”是沒有辦法用反斜線”\”轉義的,這時候只要把命令中的單引號改為雙引號就行了,格式如下: # 要 ...
  • 一般來說,構建一個 Windows 程式可以分為如下幾個步驟:定義視窗類(WNDCLASS)註冊視窗類(RegisterClass)創建視窗(CreateWindow)更新顯示視窗(UpdateWindow、ShowWindow)建立消息迴圈(GetMessage)處理消息(DispatchMess... ...
  • 曾多次想要在Linux下比較目錄a和目錄b中 文件列表 的差別,然後對目錄a比目錄b中多出的文件、少掉的文件分別做處理。但是,在網上搜索了多次也都沒找到能直接處理好的工具。 所以想了很多不少方法,自我感覺都不錯,而且網上似乎沒有這方面的文章,所以分享出來給大家。如果各位有更好的工具或者方法,盼請留下 ...
  • https://technet.microsoft.com/zh-cn/library/2008.12.linux.aspx ...
  • 前言: 本文是對Muhammad Irfan的這篇博客MySQL "Got an Error Reading Communication Packet" Errors的翻譯,如有翻譯不對或不好的地方,敬請指出,大家一起學習進步。尊重原創和翻譯勞動成果,轉載時請註明出處。謝謝! 英文原文地址:http... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...