Skip to content

Commit eaba7f5

Browse files
Merge pull request #610 from FirstCall42/views-support
Adding support for indexed views in addition to indexes on tables.
2 parents 6715663 + 34ed769 commit eaba7f5

1 file changed

Lines changed: 53 additions & 52 deletions

File tree

sp_IndexCleanup/sp_IndexCleanup.sql

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ ALTER PROCEDURE
5151
dbo.sp_IndexCleanup
5252
(
5353
@database_name sysname = NULL, /*focus on a single database*/
54-
@schema_name sysname = NULL, /*use when focusing on a single table, or to a single schema with no table name*/
55-
@table_name sysname = NULL, /*use when focusing on a single table*/
54+
@schema_name sysname = NULL, /*use when focusing on a single table/view, or to a single schema with no table name*/
55+
@table_name sysname = NULL, /*use when focusing on a single table or view*/
5656
@min_reads bigint = 0, /*only look at indexes with a minimum number of reads*/
5757
@min_writes bigint = 0, /*only look at indexes with a minimum number of writes*/
5858
@min_size_gb decimal(10,2) = 0, /*only look at indexes with a minimum size*/
@@ -139,7 +139,7 @@ BEGIN TRY
139139
ap.name
140140
WHEN N'@database_name' THEN 'the name of the database you wish to analyze'
141141
WHEN N'@schema_name' THEN 'limits analysis to tables in the specified schema when used without @table_name'
142-
WHEN N'@table_name' THEN 'the table name to filter indexes by, requires @schema_name if not dbo'
142+
WHEN N'@table_name' THEN 'the table or view name to filter indexes by, requires @schema_name if not dbo'
143143
WHEN N'@min_reads' THEN 'minimum number of reads for an index to be considered used'
144144
WHEN N'@min_writes' THEN 'minimum number of writes for an index to be considered used'
145145
WHEN N'@min_size_gb' THEN 'minimum size in GB for an index to be analyzed'
@@ -159,7 +159,7 @@ BEGIN TRY
159159
ap.name
160160
WHEN N'@database_name' THEN 'the name of a database you care about indexes in'
161161
WHEN N'@schema_name' THEN 'schema name or NULL for all schemas'
162-
WHEN N'@table_name' THEN 'table name or NULL for all tables'
162+
WHEN N'@table_name' THEN 'table (or view) name or NULL for all tables'
163163
WHEN N'@min_reads' THEN 'any positive integer or 0'
164164
WHEN N'@min_writes' THEN 'any positive integer or 0'
165165
WHEN N'@min_size_gb' THEN 'any positive decimal or 0'
@@ -1178,39 +1178,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11781178
SELECT DISTINCT
11791179
@database_id,
11801180
database_name = DB_NAME(@database_id),
1181-
schema_id = t.schema_id,
1181+
schema_id = s.schema_id,
11821182
schema_name = s.name,
1183-
object_id = t.object_id,
1184-
table_name = t.name,
1183+
object_id = i.object_id,
1184+
table_name = ISNULL(t.name, v.name),
11851185
index_id = i.index_id,
1186-
index_name = ISNULL(i.name, t.name + N''.Heap''),
1186+
index_name = ISNULL(i.name, ISNULL(t.name, v.name) + N''.Heap''),
11871187
can_compress =
11881188
CASE
11891189
WHEN p.index_id > 0
11901190
AND p.data_compression = 0
11911191
THEN 1
11921192
ELSE 0
11931193
END
1194-
FROM ' + QUOTENAME(@current_database_name) + N'.sys.tables AS t
1194+
FROM ' + QUOTENAME(@current_database_name) + N'.sys.indexes AS i
1195+
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.tables AS t
1196+
ON i.object_id = t.object_id
1197+
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.views AS v
1198+
ON i.object_id = v.object_id
11951199
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.schemas AS s
1196-
ON t.schema_id = s.schema_id
1197-
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.indexes AS i
1198-
ON t.object_id = i.object_id
1200+
ON ISNULL(t.schema_id, v.schema_id) = s.schema_id
11991201
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.partitions AS p
12001202
ON i.object_id = p.object_id
12011203
AND i.index_id = p.index_id
12021204
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.dm_db_index_usage_stats AS us
1203-
ON t.object_id = us.object_id
1205+
ON i.object_id = us.object_id
12041206
AND us.database_id = @database_id
1205-
WHERE t.is_ms_shipped = 0
1206-
AND t.type <> N''TF''
1207-
AND NOT EXISTS
1208-
(
1209-
SELECT
1210-
1/0
1211-
FROM ' + QUOTENAME(@current_database_name) + N'.sys.views AS v
1212-
WHERE v.object_id = i.object_id
1213-
)
1207+
WHERE (t.object_id IS NULL OR t.is_ms_shipped = 0)
1208+
AND (t.object_id IS NULL OR t.type <> N''TF'')
12141209
AND i.is_disabled = 0
12151210
AND i.is_hypothetical = 0';
12161211

@@ -1261,7 +1256,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12611256
END;
12621257

12631258
SET @sql += N'
1264-
AND t.object_id = @object_id';
1259+
AND i.object_id = @object_id';
12651260
END;
12661261

12671262
IF @schema_name IS NOT NULL
@@ -1284,7 +1279,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12841279
FROM ' + QUOTENAME(@current_database_name) + N'.sys.dm_db_partition_stats AS ps
12851280
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.allocation_units AS au
12861281
ON ps.partition_id = au.container_id
1287-
WHERE ps.object_id = t.object_id
1282+
WHERE ps.object_id = i.object_id
12881283
GROUP BY
12891284
ps.object_id
12901285
HAVING
@@ -1295,7 +1290,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12951290
SELECT
12961291
1/0
12971292
FROM ' + QUOTENAME(@current_database_name) + N'.sys.dm_db_partition_stats AS ps
1298-
WHERE ps.object_id = t.object_id
1293+
WHERE ps.object_id = i.object_id
12991294
AND ps.index_id IN (0, 1)
13001295
GROUP BY
13011296
ps.object_id
@@ -1307,7 +1302,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13071302
SELECT
13081303
1/0
13091304
FROM ' + QUOTENAME(@current_database_name) + N'.sys.dm_db_index_usage_stats AS ius
1310-
WHERE ius.object_id = t.object_id
1305+
WHERE ius.object_id = i.object_id
13111306
AND ius.database_id = @database_id
13121307
GROUP BY
13131308
ius.object_id
@@ -1716,9 +1711,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17161711
schema_id = s.schema_id,
17171712
schema_name = s.name,
17181713
os.object_id,
1719-
table_name = t.name,
1714+
table_name = ISNULL(t.name, v.name),
17201715
os.index_id,
1721-
index_name = ISNULL(i.name, t.name + N''.Heap''),
1716+
index_name = ISNULL(i.name, ISNULL(t.name, v.name) + N''.Heap''),
17221717
range_scan_count = SUM(os.range_scan_count),
17231718
singleton_lookup_count = SUM(os.singleton_lookup_count),
17241719
forwarded_fetch_count = SUM(os.forwarded_fetch_count),
@@ -1756,10 +1751,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17561751
NULL,
17571752
NULL
17581753
) AS os
1759-
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.tables AS t
1754+
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.tables AS t
17601755
ON os.object_id = t.object_id
1756+
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.views AS v
1757+
ON os.object_id = v.object_id
17611758
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.schemas AS s
1762-
ON t.schema_id = s.schema_id
1759+
ON ISNULL(t.schema_id, v.schema_id) = s.schema_id
17631760
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.indexes AS i
17641761
ON os.object_id = i.object_id
17651762
AND os.index_id = i.index_id
@@ -1777,7 +1774,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17771774
s.schema_id,
17781775
s.name,
17791776
os.object_id,
1780-
t.name,
1777+
ISNULL(t.name, v.name),
17811778
os.index_id,
17821779
i.name
17831780
OPTION(RECOMPILE);
@@ -1867,12 +1864,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18671864
SELECT
18681865
database_id = @database_id,
18691866
database_name = DB_NAME(@database_id),
1870-
t.object_id,
1867+
i.object_id,
18711868
i.index_id,
18721869
s.schema_id,
18731870
schema_name = s.name,
1874-
table_name = t.name,
1875-
index_name = ISNULL(i.name, t.name + N''.Heap''),
1871+
table_name = ISNULL(t.name, v.name),
1872+
index_name = ISNULL(i.name, ISNULL(t.name, v.name) + N''.Heap''),
18761873
column_name = c.name,
18771874
column_id = c.column_id,
18781875
i.is_primary_key,
@@ -1964,11 +1961,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19641961
)
19651962
THEN 0
19661963
END
1967-
FROM ' + QUOTENAME(@current_database_name) + N'.sys.tables AS t
1964+
FROM ' + QUOTENAME(@current_database_name) + N'.sys.indexes AS i
1965+
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.tables AS t
1966+
ON i.object_id = t.object_id
1967+
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.views AS v
1968+
ON i.object_id = v.object_id
19681969
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.schemas AS s
1969-
ON t.schema_id = s.schema_id
1970-
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.indexes AS i
1971-
ON t.object_id = i.object_id
1970+
ON ISNULL(t.schema_id, v.schema_id) = s.schema_id
19721971
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.index_columns AS ic
19731972
ON i.object_id = ic.object_id
19741973
AND i.index_id = ic.index_id
@@ -1983,7 +1982,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19831982
ON i.object_id = us.object_id
19841983
AND i.index_id = us.index_id
19851984
AND us.database_id = @database_id
1986-
WHERE t.is_ms_shipped = 0
1985+
WHERE (t.object_id IS NULL OR t.is_ms_shipped = 0)
19871986
AND i.type IN (1, 2)
19881987
AND i.is_disabled = 0
19891988
AND i.is_hypothetical = 0
@@ -1993,7 +1992,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19931992
1/0
19941993
FROM #filtered_objects AS fo
19951994
WHERE fo.database_id = @database_id
1996-
AND fo.object_id = t.object_id
1995+
AND fo.object_id = i.object_id
19971996
)
19981997
AND EXISTS
19991998
(
@@ -2005,7 +2004,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20052004
(
20062005
nvarchar(MAX),
20072006
N'.sys.dm_db_partition_stats ps
2008-
WHERE ps.object_id = t.object_id
2007+
WHERE ps.object_id = i.object_id
20092008
AND ps.index_id = 1
20102009
AND ps.row_count >= @min_rows
20112010
)'
@@ -2019,7 +2018,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20192018
END;
20202019

20212020
SELECT @sql += N'
2022-
AND t.object_id = @object_id';
2021+
AND i.object_id = @object_id';
20232022
END;
20242023

20252024
SELECT
@@ -2148,8 +2147,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21482147
ps.index_id,
21492148
s.schema_id,
21502149
schema_name = s.name,
2151-
table_name = t.name,
2152-
index_name = ISNULL(i.name, t.name + N''.Heap''),
2150+
table_name = ISNULL(t.name, v.name),
2151+
index_name = ISNULL(i.name, ISNULL(t.name, v.name) + N''.Heap''),
21532152
ps.partition_id,
21542153
p.partition_number,
21552154
total_rows = ps.row_count,
@@ -2158,27 +2157,29 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21582157
reserved_row_overflow_gb = SUM(ps.row_overflow_reserved_page_count) * 8. / 1024. / 1024.0, /* Convert directly to GB */
21592158
p.data_compression_desc,
21602159
i.data_space_id
2161-
FROM ' + QUOTENAME(@current_database_name) + N'.sys.tables AS t
2162-
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.indexes AS i
2163-
ON t.object_id = i.object_id
2160+
FROM ' + QUOTENAME(@current_database_name) + N'.sys.indexes AS i
2161+
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.tables AS t
2162+
ON i.object_id = t.object_id
2163+
LEFT JOIN ' + QUOTENAME(@current_database_name) + N'.sys.views AS v
2164+
ON i.object_id = v.object_id
21642165
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.schemas AS s
2165-
ON t.schema_id = s.schema_id
2166+
ON ISNULL(t.schema_id, v.schema_id) = s.schema_id
21662167
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.partitions AS p
21672168
ON i.object_id = p.object_id
21682169
AND i.index_id = p.index_id
21692170
JOIN ' + QUOTENAME(@current_database_name) + N'.sys.allocation_units AS a
21702171
ON p.partition_id = a.container_id
21712172
LEFT HASH JOIN ' + QUOTENAME(@current_database_name) + N'.sys.dm_db_partition_stats AS ps
21722173
ON p.partition_id = ps.partition_id
2173-
WHERE t.type <> N''TF''
2174+
WHERE (t.object_id IS NULL OR t.type <> N''TF'')
21742175
AND i.type IN (1, 2)
21752176
AND EXISTS
21762177
(
21772178
SELECT
21782179
1/0
21792180
FROM #filtered_objects AS fo
21802181
WHERE fo.database_id = @database_id
2181-
AND fo.object_id = t.object_id
2182+
AND fo.object_id = i.object_id
21822183
)';
21832184

21842185
IF @object_id IS NOT NULL
@@ -2189,7 +2190,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21892190
END;
21902191

21912192
SELECT @sql += N'
2192-
AND t.object_id = @object_id';
2193+
AND i.object_id = @object_id';
21932194
END;
21942195

21952196
SELECT
@@ -2199,7 +2200,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21992200
ps.index_id,
22002201
s.schema_id,
22012202
s.name,
2202-
t.name,
2203+
ISNULL(t.name, v.name),
22032204
i.name,
22042205
ps.partition_id,
22052206
p.partition_number,

0 commit comments

Comments
 (0)