Last active
June 13, 2024 22:42
-
-
Save alivarzeshi/2a4b748ac5ad1ffe8734ff04f4724894 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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:
Parameter Declarations:
Logging Table:
dbo.IndexMaintenanceLog
is created to log details of each index maintenance operation, including success or failure.Cursor Declaration and Open:
index_cursor
is declared and opened to iterate over all indexes with fragmentation greater than 10%, excluding small indexes with less than 1000 pages.Dynamic SQL Construction and Execution:
sp_executesql
.Logging:
dbo.IndexMaintenanceLog
table.Cursor Cleanup:
Benefits:
Real-World Application:
Case Study:
The financial services company implemented the dynamic SQL script for automated index maintenance. The results were:
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.