How to identify and monitor dead indexes in SQL Server (2023)

SQL Server indexes are essentially copies of the data already in the table and are sorted and filtered in various ways to improve the performance of the queries that are executed. The search, browse, and query operators are used to access SQL Server indexes.

search operators– theSeekoperator takes advantage of SQL Server's ability to seek row indexes of clustered or non-clustered indexes, and the seek can be a physical or logical operator. Index retrieval deals only with the qualifying rows and the pages that contain those qualifying rows, and therefore the search cost is lower. In simple words, it tries to get only the selected rows from the table.

scan operators– The scan operator scans the clustered index and is designed to process every row in the scanned table, regardless of whether the row is qualified or not. A sweep operator can be effective for small tables or in a situation where most of the rows are qualified. In simple terms, the scans retrieve all the rows in the table.

search operators– The search operator is used to retrieve the non-key data from the result set retrieved from the nonclustered index. Once the nonclustered index rows are retrieved, lookup operations are used to retrieve column information for those rows.

While proper use of SQL Server indexes can ensure better performance of executed queries, and therefore of SQL Server in general, misconfiguring or missing on-demand configuration can significantly degrade query performance. executed. Unnecessary indexes not used by queries can also be problematic.

SQL Server indexes are a great tool to improve the performance of SELECT queries, but at the same time, SQL Server indexes have a negative impact on data updates. The INSERT, UPDATE, and DELETE operations cause the index to be updated, thereby duplicating the data already in the table. This increases transaction and query execution times and can often result in very frequent hangs, hangs, deadlocks, and execution timeouts. For large databases or tables, storage space is also affected by redundant indexes. A key goal of any SQL Server DBA is index management, including creating needed indexes but dropping unused indexes.

Find Unused Indexes

SQL Server exposes a significant amount of index information through Dynamic Management Views (DMVs). The dm_db_index_usage_stats DMV displays important information about index usage and can be a useful tool for identifying unused SQL Server indexes. When an index is used for the first time, a new row is created in the DMV dm_db_index_usage_stats and then updated each time an index is used. However, as with all DMVs, the data is in thedm_db_index_usage_statscontain only the data since the last restart of the SQL Server service (a restart of the SQL Server service resets the data in the DMV). Therefore, it is important that sufficient time has elapsed since the last SQL Server restart so that it can correctly determine which indexes are good candidates for deletion.

A simple query that can be used to get the list of unused indexes in SQL Server (updated indexes that are not used in get, browse, or seek operations) is as follows:

(Video) Indexes in sql server Part 35

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

sixteen

17

18

19

CHOOSE

objects.Name AND table name,

indexes.Name AND indexname,

dm_db_index_usage_stats.search_user,

dm_db_index_usage_stats.user scans,

dm_db_index_usage_stats.user_updates

VON

System.dm_db_index_usage_stats

INTERNAL MEET A System.objects ONE dm_db_index_usage_stats.OBJECT IDENTIFICATION = objects.OBJECT IDENTIFICATION

INTERNAL MEET A System.indexes ONE indexes.index_id = dm_db_index_usage_stats.index_id mi dm_db_index_usage_stats.OBJECT IDENTIFICATION = indexes.OBJECT IDENTIFICATION

WO

mi

dm_db_index_usage_stats.user_searches = 0

mi

dm_db_index_usage_stats.search_user = 0

mi

dm_db_index_usage_stats.user scans = 0

DOMAIN VON

dm_db_index_usage_stats.user_updates DESCRIPTION


The above query returns all unused indices of all types. This query is often found on the internet, but it is not an ideal/complete option. Using this query to find and clean up unused indexes can cause unexpected behavior because this query does not honor primary key and unique key constraints when collecting unused index data. Primary and unique key constraint indexes can be "unused", but removing these indexes can be problematic. To avoid this scenario, the above query should be refined by adding two lines of code after WHERE to exclude the collection's primary keys and unique keys as unused and possibly deleted.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

sixteen

17

18

19

20

21

22

CHOOSE

objects.Name AND table name,

indexes.Name AND indexname,

dm_db_index_usage_stats.search_user,

dm_db_index_usage_stats.user scans,

dm_db_index_usage_stats.user_updates

VON

System.dm_db_index_usage_stats

INTERNAL MEET A System.objects ONE dm_db_index_usage_stats.OBJECT IDENTIFICATION = objects.OBJECT IDENTIFICATION

INTERNAL MEET A System.indexes ONE indexes.index_id = dm_db_index_usage_stats.index_id mi dm_db_index_usage_stats.OBJECT IDENTIFICATION = indexes.OBJECT IDENTIFICATION

WO

indexes.is_primary_key = 0 -- This condition clears the primary key constant

mi

indexes. It's unique = 0 -- This condition removes the unique key constraint

mi

dm_db_index_usage_stats. user_searches = 0

mi

dm_db_index_usage_stats.search_user = 0

mi

dm_db_index_usage_stats.user scans = 0

DOMAIN VON

dm_db_index_usage_stats.user_updates DESCRIPTION


The above query lists all unused queries that are not primary and unique keys, but also lists all unused indexes that SQL Server has not worked with. The user_updates column in the dm_db_index_usage_stats DMV indicates where the index was updated because the application loaded some data changes, so the index was updated. For thatdm_db_index_usage_stats.user_updates <> 0Conditions must be added to the above script.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

sixteen

17

18

19

20

21

22

23

24

CHOOSE

objects.Name AND table name,

indexes.Name AND indexname,

dm_db_index_usage_stats.search_user,

dm_db_index_usage_stats.user scans,

dm_db_index_usage_stats.user_updates

VON

System.dm_db_index_usage_stats

INTERNAL MEET A System.objects ONE dm_db_index_usage_stats.OBJECT IDENTIFICATION = objects.OBJECT IDENTIFICATION

INTERNAL MEET A System.indexes ONE indexes.index_id = dm_db_index_usage_stats.index_id mi dm_db_index_usage_stats.OBJECT IDENTIFICATION = indexes.OBJECT IDENTIFICATION

WO

indexes.is_primary_key = 0 --This line removes the primary key constant

mi

indexes. It's unique = 0 --This line prevents the constancy of unique keys

mi

dm_db_index_usage_stats.user_updates <> 0 -- This line drops indexes that SQL Server has not worked with

mi

dm_db_index_usage_stats. user_searches = 0

mi

dm_db_index_usage_stats.search_user = 0

mi

dm_db_index_usage_stats.user scans = 0

DOMAIN VON

dm_db_index_usage_stats.user_updates DESCRIPTION

(Video) How do SQL Indexes Work

So after identifying and listing the unused SQL Server indexes, one can determine which indexes are safe to drop, but again, great care must be taken.

What unused indexes should not be removed?

unique constraints

An example of other reasons for caution is that the index may show up as unused but may impose a uniqueness constraint and the query optimizer may need that index. The query optimizer can use a uniqueness guarantee to determine which logical transformations and physical operations to use to get accurate results. The query optimizer considers a uniqueness guarantee to perform certain operations, but this is not reflected in the index usage statistics without physically accessing the index in the final execution plan. With this in mind, any single index or constraint removal should be done with extreme caution.

use statistics

Another point to consider is the possibility of the query optimizer using statistics associated with this index, even in situations where the final execution plan does not use access to this index. Estimating cardinality, loading candidate statistics, and finally creating a complete query execution plan are completely separate actions.

Finally, removing the index can also remove the attached index statistics. This can affect the quality of the query execution plan when the statement is recompiled. This is because the query execution plan can use the index statistics, even if the index does not physically exist in the final execution plan, to calculate the cardinality estimate on which the final execution plan significantly depends.

These are just some of the potential issues that can occur when deleting the index, and therefore such action should be planned with a proper test and recovery plan in case something goes wrong. Also, a few unused SQL Server indexes do not necessarily indicate a problem, but if the number of unused indexes grows at a more or less constant rate over time, or if the growth is sudden, this should be checked and considered. drawn. cases

Deletion of the indices

(Video) Indexes in SQL Server | Use Indexes for Faster Search in SQL | SQL Interview Questions

The following script creates a drop script for all unused indexes. It is based on the above script, which is more secure, but is provided as a guide and deletion of indexes is at the discretion of the user. The purpose ID of the script to help identify the indexes.Candidatesto delete so don't decide this in a bubble

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

sixteen

17

18

19

20

CHOOSE 'DROP-INDEX'+OBJECT NAME(dm_db_index_usage_stats.object identification)+'.'+indexes.Name AND Drop_Index, search_user, user scans, user_searches, user_updates

VON

System.dm_db_index_usage_stats

INTERNAL MEET A System.objects ONE dm_db_index_usage_stats.OBJECT IDENTIFICATION = objects.OBJECT IDENTIFICATION

INTERNAL MEET A System.indexes ONE indexes.index_id = dm_db_index_usage_stats.index_id mi dm_db_index_usage_stats.OBJECT IDENTIFICATION = indexes.OBJECT IDENTIFICATION

WO

indexes.is_primary_key = 0 --This line removes the primary key constant

mi

indexes. It's unique = 0 --This line prevents the constancy of unique keys

mi

dm_db_index_usage_stats.user_updates <> 0 -- This line drops indexes that SQL Server has not worked with

mi

dm_db_index_usage_stats. user_searches = 0

mi

dm_db_index_usage_stats.search_user = 0

mi

dm_db_index_usage_stats.user scans = 0

DOMAIN VON

dm_db_index_usage_stats.user_updates DESCRIPTION


How to identify and monitor dead indexes in SQL Server (1)

Helpful Resources:


  • Author
  • recent posts

Nikola Dimitrijevic

(Video) Understanding and using indexes on SQL Server

Nikola has been a computer geek and SQL enthusiast since 1981, determined to become a freak. He specialized in auditing, compliance and performance monitoring of SQL Server.

Military aviation enthusiast and die-hard model aircraft builder. extreme sports fan; Skydiving and bungee jumping instructor. Once serious, now just a recreational photographer

See all posts from Nikola Dimitrijevic

Last posts by Nikola Dimitrijevic(See everything)

(Video) Columnstore index in sql server (tutorial)

  • SQL Server Trace Flags Guide; from -1 to 840- March 4, 2019
  • SQL Server WRITELOG wait type handling- 13. June 2018
  • SQL Server Performance Counters (Batch Requests/sec or Transactions/sec): What to Monitor and Why- 5. June 2018

Related Posts:

  1. How to monitor the total size of SQL Server indexes
  2. SQL Server Indexes - String Introduction
  3. Collect SQL Server index statistics and usage information
  4. SQL Server nonclustered indexes with included columns
  5. How to monitor SQL Server tempdb database

Videos

1. SQL Server 33 - Indexes
(Caleb Curry)
2. SQL Server - Identifying and Resolving Deadlock
(Virendra Wadekar)
3. SQL Monitor and Deadlocks
(Redgate Videos)
4. Creating and Identifying Deadlocks in SQL Server
(Procure SQL LLC)
5. SQL Server Execution Plan Operators
(Brent Ozar Unlimited)
6. SQL Server 2012 (70-462) - 9 Performance and Monitoring
(Free Training)

References

Top Articles
Latest Posts
Article information

Author: Frankie Dare

Last Updated: 12/07/2023

Views: 6667

Rating: 4.2 / 5 (53 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Frankie Dare

Birthday: 2000-01-27

Address: Suite 313 45115 Caridad Freeway, Port Barabaraville, MS 66713

Phone: +3769542039359

Job: Sales Manager

Hobby: Baton twirling, Stand-up comedy, Leather crafting, Rugby, tabletop games, Jigsaw puzzles, Air sports

Introduction: My name is Frankie Dare, I am a funny, beautiful, proud, fair, pleasant, cheerful, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.