Monday, October 30, 2023

SQL Index

 1 Index Overview 1

2 Terms 2

2.1 SYS.DM_DB_INDEX_PHYSICAL_STATS 2

3 What is index fragmentation? 2

4 Types of Fragmentation 2

4.1 INTERNAL FRAGMENTATION 2

4.2 External Fragmentation: 2

5 How to measure fragmentation? 2

5.1 To Find out fragmentation level of a given database 2

6 How to address fragmentation issues with indexes? 3

6.1 OPTION 1: REACTIVE APPROACH 3

6.1.1 INDEX REBUILD - TO RECREATE ALL INDEX PAGES 3

6.1.2 INDEX REORGANIZE - TO REARRANGE THE FRAGMENTED INDEX PAGES 3

6.2 OPTION 2: PROACTIVE APPROACH 3

7 Index Management Example 4

8 Page Density 5


  1. Index Overview 

Applies to:  SQL Server  Azure SQL Database  Azure SQL Managed Instance  Analytics Platform System (PDW)


https://learn.microsoft.com/en-us/sql/relational-databases/indexes/reorganize-and-rebuild-indexes?view=sql-server-ver16


  •  Optimize index maintenance to improve query performance and reduce resource consumption.

  • The Database Engine automatically modifies indexes whenever insert, update, or delete operations are made to the underlying data

  • heavily fragmented indexes can degrade query performance because additional I/O may be required to read the data required by the query


  1. Terms 

    1. SYS.DM_DB_INDEX_PHYSICAL_STATS

  2. What is index fragmentation?

  • A phenomena in which the data pages are not in continuation with relevant index pages.

  • Means, index pages and data pages are not in sync.

  • Impact:

    • Index scan (reads) and index seek (searches) takes more time to execute. 

    • Adverse impact on query performance. Means, the queries run slow.

  1. Types of Fragmentation 

    1. INTERNAL FRAGMENTATION

  • When records are stored non-contiguously inside the page,  then it is called internal fragmentation. In other words, internal fragmentation is said to occur if there is unused space between records in a page. 

  • This fragmentation occurs through the process of data modifications (INSERT, UPDATE, and DELETE statements) that are made against the table  and therefore, to the indexes defined on the table.

  1. External Fragmentation:

  • External Fragmentation: When on disk, the physical storage of pages and extents is not contiguous. When the extents of a table are not physically stored  contiguously on disk, switching from one extent to another  (EXTENT SWITCH) causes higher disk rotations, and this is called Extent Fragmentation.

  1. How to measure fragmentation?

SELECT * FROM SYS.DM_DB_INDEX_PHYSICAL_STATS (null, null, null, null, null)

1ST PARAMETER: DATABASE ID. OR NULL   : MEANS ALL DATABASES

2ND PARAMETER: OBJECT ID. OR NULL   : MEANS ALL TABLES & VIEWS

3RD PARAMETER: INDEX ID. OR NULL   : MEANS ALL INDEXES

4TH PARAMETER: PARTITION NUMBER. OR NULL   : MEANS ALL PARTITIONS

5TH PARAMETER: NULL  (SAMPLED ** / DETAILED)


select * from sys.dm_db_index_physical_stats(db_id(N'AdventureWorks2022'), NULL, NULL, NULL , 'DETAILED')

  1. To Find out fragmentation level of a given database

--This query will give DETAILED information

--CAUTION : It may take very long time, depending on the number of tables in the DB

USE AdventureWorks

GO

SELECT object_name(IPS.object_id) AS [TableName], 

   SI.name AS [IndexName], 

   IPS.Index_type_desc, 

   IPS.avg_fragmentation_in_percent, 

   IPS.avg_fragment_size_in_pages, 

   IPS.avg_page_space_used_in_percent, 

   IPS.record_count, 

   IPS.ghost_record_count,

   IPS.fragment_count, 

   IPS.avg_fragment_size_in_pages

FROM sys.dm_db_index_physical_stats(db_id(N'AdventureWorks'), NULL, NULL, NULL , 'DETAILED') IPS

   JOIN sys.tables ST WITH (nolock) ON IPS.object_id = ST.object_id

   JOIN sys.indexes SI WITH (nolock) ON IPS.object_id = SI.object_id AND IPS.index_id = SI.index_id

WHERE ST.is_ms_shipped = 0

ORDER BY 1,5

GO



  1. How to address fragmentation issues with indexes?

    1. OPTION 1: REACTIVE APPROACH

      1. INDEX REBUILD - TO RECREATE ALL INDEX PAGES

  • APPLICABLE FOR HIGHER FRAGMENTATION LEVELS. ABOVE 30% 

  • SYNTAX:  ALTER INDEX <INDEXNAME> ON <TABLENAME>  REBUILD

  1. INDEX REORGANIZE - TO REARRANGE THE FRAGMENTED INDEX PAGES

  • APPLICABLE FOR LOWER FRAGMENTATION LEVELS. BETWEEN 15% AND 30%

  • SYNTAX: ALTER INDEX <INDEXNAME> ON <TABLENAME>  REORGANIZE

  1. OPTION 2: PROACTIVE APPROACH

  • ENSURE AUTOMATED, SCHEDULED INDEX REORGANIZATION @ "DATABASE  INTENANCE PLANS".  THIS PREVENTS FRAGMENTATION.

STEPS TO CONFIGURE DATABASE MAINTENANCE PLANS :

STEP 1: LAUNCH SSMS >> CONNECT TO SERVER 

STEP 2: RIGHT CLICK AGENT > START

STEP 3: FROM SERVER >> MANAGEMENT >> MAINTENANCE PLANS >> MAINTENANCE PLAN WIZARD >> 

SPECIFY A NAME > SPECIFY A SCHEDULE [EVERYDAY @ 12 AM SERVER TIME] > 

SELECT BELOW ITEMS:

a. INDEX REORGANIZE

b. UPDATE STATISTICS

SPECIFY THE ORDER AS LISTED ABOVE. 


STEP 4: INDEX REROGANIZE:: SELECT ALL DATABASES

COMPRESS LARGE OBJECTS 

SCAN TYPE (FAST, SAMPLED, DETAILED *)

OPTIMIZATION OPTIONS:

FRAGMENATION CONDITION   > 15%

PAGE COUNT CONDITION > 1000

USAGE CONDITION 7 DAYS


STEP 5: UPDATE STATISTICS::SELECT ALL DATABASES

FULL SCAN

STEP 6: WRITE REPORT TO A TXT FILE [LOG]  > FINISH > CLOSE. 

STEP 7: OPTIONAL.

RIGHT CLICK MAINTENANCE PLAN > EXECUTE




  1. Index Management Example

SYS.DM_DB_INDEX_PHYSICAL_STATS -REBUILD / REORGANIZE

USE MASTER 

GO

-- STEP 1: REPORT FRAGMENTATION FOR ALL INDEXES ACROSS ALL DATABASES?

SELECT * FROM SYS.DM_DB_INDEX_PHYSICAL_STATS(null, null, null, null, NULL)


-- STEP 2: REPORT HEAVILY FRAGMENTED INDEXES ACROSS ALL DATABASES?

SELECT * FROM SYS.DM_DB_INDEX_PHYSICAL_STATS(null, null, null, null, NULL)

WHERE avg_fragmentation_in_percent >  80


-- STEP 3: HOW TO FIND FRAGMENTAITON DETAILS FOR A GIVEN DATABASE & OBJECT?

SELECT * FROM SYS.DM_DB_INDEX_PHYSICAL_STATS(6, 309576141, 1, 1, NULL)


-- STEP 4: IDENTIFY DATABASE NAME

SELECT DB_NAME(6)  -- SSASSBS


-- STEP 5: CONNECT TO ABOVE DATABASE, IDENTIFY THE TABLE NAME

USE SSASSBS

GO

SELECT OBJECT_NAME(309576141)  -- FactInternetSales  


-- STEP 7: IDENTIFY THE INDEX NAME FOR ABOVE TABLE

SELECT * FROM SYS.INDEXES WHERE OBJECT_ID = 309576141  -- PK_FactInternetSales_SalesOrderNumber_SalesOrderLineNumber

 


-- STEP 8: FOR HIGHER FRAGMENTATION VALUES, WE NEED TO REBUILD THE INDEX

ALTER INDEX PK_FactInternetSales_SalesOrderNumber_SalesOrderLineNumber

ON FactInternetSales

REBUILD 


-- OR


-- STEP 8: FOR MODERATE FRAGMENTATION VALUES, WE NEED TO REORGANISE THE INDEX

ALTER INDEX PK_FactInternetSales_SalesOrderNumber_SalesOrderLineNumber

ON FactInternetSales

REORGANIZE 



-- STEP 9: VERIFY THE FRAGMENTATION LEVELS AFTER INDEX REBUILD OR REORGANIZE

SELECT * FROM SYS.DM_DB_INDEX_PHYSICAL_STATS(6, 309576141, 1, 1, NULL)

  1. Page Density

  • Each page in the database can contain a variable number of rows. If rows take all space on a page, page density is 100%. If a page is empty, page density is 0%.

  • When page density is low, more pages are required to store the same amount of data. This means that more I/O is necessary to read and write this data, and more memory is necessary to cache this data. When memory is limited, fewer pages required by a query are cached, causing even more disk I/O. Consequently, low page density negatively impacts performance.

  • To avoid lowering page density unnecessarily, Microsoft does not recommend setting fill factor to values other than 100 or 0,