-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsp_ResetMissingIndexDMV.sql
More file actions
100 lines (83 loc) · 3.18 KB
/
sp_ResetMissingIndexDMV.sql
File metadata and controls
100 lines (83 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
CREATE OR ALTER PROCEDURE dbo.usp_ResetMissingIndexDMV
AS
BEGIN
SET NOCOUNT ON;
DROP TABLE IF EXISTS #TargetTables;
SELECT DISTINCT
PARSENAME(REPLACE(REPLACE(mid.[statement], '[', ''), ']', ''), 2) AS schema_name,
PARSENAME(REPLACE(REPLACE(mid.[statement], '[', ''), ']', ''), 1) AS table_name
INTO #TargetTables
FROM sys.dm_db_missing_index_details AS mid
WHERE mid.database_id = DB_ID();
DROP TABLE IF EXISTS #IndexTargets;
SELECT
tt.schema_name,
tt.table_name,
MIN(c.name) AS column_name
INTO #IndexTargets
FROM #TargetTables AS tt
INNER JOIN sys.tables AS t
ON t.name = tt.table_name COLLATE DATABASE_DEFAULT -- ← temp table vs catalog
AND t.schema_id = SCHEMA_ID(tt.schema_name COLLATE DATABASE_DEFAULT) -- ← SCHEMA_ID() input
INNER JOIN sys.columns AS c
ON c.object_id = t.object_id
AND c.is_nullable = 0
AND c.is_computed = 0
INNER JOIN sys.types AS ty
ON ty.user_type_id = c.user_type_id
AND ty.name COLLATE DATABASE_DEFAULT NOT IN ( -- ← catalog vs literal
'text', 'ntext', 'image',
'xml', 'geography', 'geometry',
'hierarchyid', 'sql_variant'
)
GROUP BY
tt.schema_name,
tt.table_name;
DECLARE
@schema_name NVARCHAR(128),
@table_name NVARCHAR(128),
@column_name NVARCHAR(128),
@index_name NVARCHAR(128),
@sql NVARCHAR(MAX);
DECLARE cur CURSOR LOCAL FAST_FORWARD FOR
SELECT schema_name, table_name, column_name
FROM #IndexTargets;
OPEN cur;
FETCH NEXT FROM cur INTO @schema_name, @table_name, @column_name;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @index_name = N'IX_DMVReset_Temp_'
+ @table_name
+ N'_'
+ @column_name;
IF LEN(@index_name) > 128
SET @index_name = LEFT(@index_name, 128);
BEGIN TRY
SET @sql = N'CREATE INDEX '
+ QUOTENAME(@index_name)
+ N' ON '
+ QUOTENAME(@schema_name) + N'.' + QUOTENAME(@table_name)
+ N' (' + QUOTENAME(@column_name) + N')'
+ N' WHERE ' + QUOTENAME(@column_name) + N' IS NULL;';
EXEC sp_executesql @sql;
SET @sql = N'DROP INDEX '
+ QUOTENAME(@index_name)
+ N' ON '
+ QUOTENAME(@schema_name) + N'.' + QUOTENAME(@table_name) + N';';
EXEC sp_executesql @sql;
PRINT N'Reset DMV entry for: '
+ QUOTENAME(@schema_name) + N'.' + QUOTENAME(@table_name)
+ N' (column: ' + @column_name + N')';
END TRY
BEGIN CATCH
PRINT N'SKIPPED '
+ QUOTENAME(@schema_name) + N'.' + QUOTENAME(@table_name)
+ N' — '
+ ERROR_MESSAGE();
END CATCH;
FETCH NEXT FROM cur INTO @schema_name, @table_name, @column_name;
END;
CLOSE cur;
DEALLOCATE cur;
END;
GO