Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save alivarzeshi/dc59766ba52d77c851a9d7440d39de0a to your computer and use it in GitHub Desktop.
Save alivarzeshi/dc59766ba52d77c851a9d7440d39de0a to your computer and use it in GitHub Desktop.
-- Step 1: Create a temporary table to hold the index fragmentation information
IF OBJECT_ID('tempdb..#IndexFragmentation') IS NOT NULL
DROP TABLE #IndexFragmentation;
CREATE TABLE #IndexFragmentation (
DatabaseName NVARCHAR(128),
SchemaName NVARCHAR(128),
TableName NVARCHAR(128),
IndexName NVARCHAR(128),
Fragmentation FLOAT
);
-- Step 2: Populate the temporary table with index fragmentation information
INSERT INTO #IndexFragmentation (DatabaseName, SchemaName, TableName, IndexName, Fragmentation)
SELECT
DB_NAME() AS DatabaseName,
sch.name AS SchemaName,
tbl.name AS TableName,
idx.name AS IndexName,
idxstats.avg_fragmentation_in_percent AS Fragmentation
FROM
sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS idxstats
INNER JOIN sys.tables AS tbl ON idxstats.object_id = tbl.object_id
INNER JOIN sys.schemas AS sch ON tbl.schema_id = sch.schema_id
INNER JOIN sys.indexes AS idx ON idxstats.object_id = idx.object_id AND idxstats.index_id = idx.index_id
WHERE
idxstats.avg_fragmentation_in_percent > 10; -- Considering indexes with fragmentation > 10%
-- Step 3: Declare variables for dynamic SQL
DECLARE @DatabaseName NVARCHAR(128),
@SchemaName NVARCHAR(128),
@TableName NVARCHAR(128),
@IndexName NVARCHAR(128),
@Fragmentation FLOAT,
@sql NVARCHAR(MAX);
-- Step 4: Create a cursor to iterate through the fragmented indexes
DECLARE IndexCursor CURSOR FOR
SELECT DatabaseName, SchemaName, TableName, IndexName, Fragmentation
FROM #IndexFragmentation;
OPEN IndexCursor;
FETCH NEXT FROM IndexCursor INTO @DatabaseName, @SchemaName, @TableName, @IndexName, @Fragmentation;
-- Step 5: Loop through the indexes and generate the maintenance scripts
WHILE @@FETCH_STATUS = 0
BEGIN
-- Reorganize indexes with fragmentation between 10% and 30%
IF @Fragmentation BETWEEN 10 AND 30
BEGIN
SET @sql = N'ALTER INDEX [' + @IndexName + N'] ON [' + @SchemaName + N'].[' + @TableName + N'] REORGANIZE;';
END
-- Rebuild indexes with fragmentation > 30%
ELSE IF @Fragmentation > 30
BEGIN
SET @sql = N'ALTER INDEX [' + @IndexName + N'] ON [' + @SchemaName + @TableName + N'] REBUILD;';
END
-- Execute the dynamically constructed SQL
EXEC sp_executesql @sql;
-- Fetch the next fragmented index
FETCH NEXT FROM IndexCursor INTO @DatabaseName, @SchemaName, @TableName, @IndexName, @Fragmentation;
END
-- Step 6: Close and deallocate the cursor
CLOSE IndexCursor;
DEALLOCATE IndexCursor;
-- Step 7: Drop the temporary table
DROP TABLE #IndexFragmentation;
@alivarzeshi
Copy link
Author

Title:

"Dynamic SQL Script for Generating Index Maintenance Scripts in SQL Server"

Common Usage:

Dynamic SQL is frequently used in SQL Server to generate and execute T-SQL statements that are constructed at runtime. This is particularly useful in scenarios where the exact SQL statements to be executed depend on variable inputs or require flexibility based on the current database schema.

Real Case Study:

Scenario:

A common real-world scenario is performing index maintenance on a database. Depending on the size and usage of tables, it is often necessary to rebuild or reorganize indexes to maintain performance. The following script dynamically generates and executes index maintenance statements based on the fragmentation levels of indexes in a database.

Explanation:

  1. Temporary Table Creation: A temporary table #IndexFragmentation is created to store the index fragmentation information.
  2. Populating Temporary Table: The sys.dm_db_index_physical_stats DMV is used to gather fragmentation details of all indexes. The results are inserted into the temporary table, filtering out indexes with fragmentation greater than 10%.
  3. Declaring Variables: Variables for dynamic SQL are declared to store information fetched from the cursor.
  4. Cursor Declaration and Open: A cursor is declared and opened to iterate through the fragmented indexes stored in the temporary table.
  5. Dynamic SQL Generation and Execution: Based on the fragmentation level, dynamic SQL statements are constructed to either reorganize or rebuild indexes. These statements are then executed using sp_executesql.
  6. Cursor Cleanup: The cursor is closed and deallocated.
  7. Temporary Table Cleanup: The temporary table is dropped to clean up resources.

Benefits:

  • Dynamic SQL Flexibility: The script dynamically constructs and executes index maintenance statements, allowing it to adapt to the current state of the database.
  • Improved Performance: Regular index maintenance helps in maintaining database performance by reducing fragmentation.
  • Automated Maintenance: This script can be scheduled as a SQL Server Agent job to automate regular index maintenance.

This example showcases the power of dynamic SQL in managing complex and variable database maintenance tasks efficiently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment