Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save alivarzeshi/2a4b748ac5ad1ffe8734ff04f4724894 to your computer and use it in GitHub Desktop.
Save alivarzeshi/2a4b748ac5ad1ffe8734ff04f4724894 to your computer and use it in GitHub Desktop.
-- Parameter Declarations
DECLARE @DatabaseName NVARCHAR(128);
DECLARE @SchemaName NVARCHAR(128);
DECLARE @TableName NVARCHAR(128);
DECLARE @IndexName NVARCHAR(128);
DECLARE @Fragmentation FLOAT;
DECLARE @sql NVARCHAR(MAX);
-- Create a table to log index maintenance details
IF OBJECT_ID('dbo.IndexMaintenanceLog', 'U') IS NULL
BEGIN
CREATE TABLE dbo.IndexMaintenanceLog (
LogID INT IDENTITY(1,1) PRIMARY KEY,
DatabaseName NVARCHAR(128),
SchemaName NVARCHAR(128),
TableName NVARCHAR(128),
IndexName NVARCHAR(128),
Fragmentation FLOAT,
ActionTaken NVARCHAR(50),
LogDate DATETIME DEFAULT GETDATE(),
Success BIT,
ErrorMessage NVARCHAR(MAX)
);
END
-- Create a cursor to iterate over all indexes with fragmentation greater than 10%
DECLARE index_cursor CURSOR FOR
SELECT
DB_NAME() AS DatabaseName,
s.name AS SchemaName,
t.name AS TableName,
i.name AS IndexName,
ps.avg_fragmentation_in_percent AS Fragmentation
FROM
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ps
JOIN sys.indexes AS i ON ps.object_id = i.object_id AND ps.index_id = i.index_id
JOIN sys.tables AS t ON ps.object_id = t.object_id
JOIN sys.schemas AS s ON t.schema_id = s.schema_id
WHERE
ps.avg_fragmentation_in_percent > 10
AND i.type_desc IN ('CLUSTERED', 'NONCLUSTERED')
AND ps.page_count > 1000; -- Exclude small indexes
OPEN index_cursor;
FETCH NEXT FROM index_cursor INTO @DatabaseName, @SchemaName, @TableName, @IndexName, @Fragmentation;
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
-- Construct the dynamic SQL for index maintenance
IF @Fragmentation BETWEEN 10 AND 30
BEGIN
SET @sql = N'ALTER INDEX [' + @IndexName + N'] ON [' + @SchemaName + N'].[' + @TableName + N'] REORGANIZE;';
INSERT INTO dbo.IndexMaintenanceLog (DatabaseName, SchemaName, TableName, IndexName, Fragmentation, ActionTaken)
VALUES (@DatabaseName, @SchemaName, @TableName, @IndexName, @Fragmentation, 'REORGANIZE');
END
ELSE IF @Fragmentation > 30
BEGIN
SET @sql = N'ALTER INDEX [' + @IndexName + N'] ON [' + @SchemaName + N'].[' + @TableName + N'] REBUILD;';
INSERT INTO dbo.IndexMaintenanceLog (DatabaseName, SchemaName, TableName, IndexName, Fragmentation, ActionTaken)
VALUES (@DatabaseName, @SchemaName, @TableName, @IndexName, @Fragmentation, 'REBUILD');
END
-- Execute the dynamic SQL
EXEC sp_executesql @sql;
-- Log success
UPDATE dbo.IndexMaintenanceLog
SET Success = 1
WHERE DatabaseName = @DatabaseName AND SchemaName = @SchemaName AND TableName = @TableName AND IndexName = @IndexName;
END TRY
BEGIN CATCH
-- Log failure
UPDATE dbo.IndexMaintenanceLog
SET Success = 0, ErrorMessage = ERROR_MESSAGE()
WHERE DatabaseName = @DatabaseName AND SchemaName = @SchemaName AND TableName = @TableName AND IndexName = @IndexName;
END CATCH
-- Fetch the next fragmented index
FETCH NEXT FROM index_cursor INTO @DatabaseName, @SchemaName, @TableName, @IndexName, @Fragmentation;
END
-- Close and deallocate the cursor
CLOSE index_cursor;
DEALLOCATE index_cursor;
@alivarzeshi
Copy link
Author

Title:

"Dynamic SQL Script for Automating Index Rebuild and Reorganize Operations in SQL Server"

Common Usage:

Dynamic SQL is commonly used in SQL Server to create and execute SQL statements at runtime, allowing for flexible and dynamic database operations. One of the most important and useful applications of dynamic SQL is in automating index maintenance tasks, such as rebuilding and reorganizing indexes based on their fragmentation levels.

Real Case Study:

Scenario:

A financial services company experienced performance degradation due to high index fragmentation in their SQL Server databases. Manually identifying and maintaining fragmented indexes was time-consuming and impractical. They needed an automated solution to regularly monitor and maintain their indexes, ensuring optimal performance.

Explanation:

  1. Parameter Declarations:

    • Variables to store database, schema, table, index names, fragmentation level, and the dynamic SQL statement are declared.
  2. Logging Table:

    • A table dbo.IndexMaintenanceLog is created to log details of each index maintenance operation, including success or failure.
  3. Cursor Declaration and Open:

    • A cursor named index_cursor is declared and opened to iterate over all indexes with fragmentation greater than 10%, excluding small indexes with less than 1000 pages.
  4. Dynamic SQL Construction and Execution:

    • Inside the loop, dynamic SQL statements for reorganizing or rebuilding indexes are constructed based on the fragmentation level.
    • The dynamic SQL statement is executed using sp_executesql.
  5. Logging:

    • Index maintenance actions and their results (success or failure) are logged in the dbo.IndexMaintenanceLog table.
  6. Cursor Cleanup:

    • After processing all fragmented indexes, the cursor is closed and deallocated to release resources.

Benefits:

  • Automation: Automates the process of maintaining indexes, reducing the need for manual intervention.
  • Performance Improvement: Regular index maintenance ensures optimal database performance by reducing fragmentation.
  • Error Handling and Logging: Provides detailed logging of index maintenance operations, including success and error messages, for auditing and troubleshooting.
  • Scalability: Easily scalable to handle additional indexes and databases as they are added to the instance.

Real-World Application:

Case Study:

The financial services company implemented the dynamic SQL script for automated index maintenance. The results were:

  • Improved Performance: Regular index maintenance reduced query execution times and improved overall database performance.
  • Operational Efficiency: The DBA team saved significant time previously spent on manual index maintenance, allowing them to focus on other critical tasks.
  • Enhanced Reliability: Automated and regular index maintenance ensured consistent and reliable database performance.

Conclusion:

Dynamic SQL in T-SQL offers powerful capabilities for automating complex tasks like index maintenance, providing flexibility and reliability in managing SQL Server environments. The provided script demonstrates how to leverage dynamic SQL to create efficient, scalable, and automated solutions for routine database maintenance tasks.

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