How to select info about indexes with specified columns from all databases in the instance using TSQL?
-
08-01-2021 - |
Question
This query selects all the indexes - its names, fragmentation, and some other parameters from the current database.
select
idx.[name] as [index_name],
sc.[name] as [schema_name],
obj.[name] as [table_name],
ips.[avg_fragmentation_in_percent] as [fragmentation_percent]
from sys.indexes as idx
inner join sys.objects as obj on idx.object_id = obj.object_id
inner join sys.schemas as sc on obj.schema_id = sc.schema_id
cross apply sys.dm_db_index_physical_stats( DB_ID(), idx.object_id, idx.index_id, NULL ,'LIMITED') AS ips
where idx.[name] is not NULL
order by [fragmentation_percent] desc;
Now I need to select all the indexes with specified columns from all databases. I can use USE [dbname]
when I execute the statement manually, but I need to put it in a cursor, so I cannot write USE [dbname]
in a cursor.
How can I substitute the database selection in the ...CROSS APPLY sys.dm_db_index_physical_stats( DB_ID(), ...
part of my statement?
Help will be much appreciated to show how can I select all database indexes with a single query.
Something like this:
declare cr_index cursor
for
exec(@dynamicUSE)
select
idx.[name] as [index_name],
sc.[name] as [schema_name],
obj.[name] as [table_name],
ips.[avg_fragmentation_in_percent] as [fragmentation_percent]
from sys.indexes as idx
inner join sys.objects as obj on idx.object_id = obj.object_id
inner join sys.schemas as sc on obj.schema_id = sc.schema_id
cross apply sys.dm_db_index_physical_stats( DB_ID(), idx.object_id, idx.index_id, NULL ,'LIMITED') AS ips
where idx.[name] is not NULL
order by [fragmentation_percent] desc;
Solution
You can do dynamic SQL in a cursor to do it on every database on the server that way :
DECLARE @DB_Name varchar(100)
DECLARE @Command nvarchar(1000)
DECLARE database_cursor CURSOR FOR
SELECT name FROM MASTER.sys.sysdatabases
OPEN database_cursor
FETCH NEXT FROM database_cursor INTO @DB_Name
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Command = 'USE [' + @DB_Name + ']; select
idx.[name] as [index_name],
sc.[name] as [schema_name],
obj.[name] as [table_name],
ips.[avg_fragmentation_in_percent] as [fragmentation_percent]
from sys.indexes as idx
inner join sys.objects as obj on idx.object_id = obj.object_id
inner join sys.schemas as sc on obj.schema_id = sc.schema_id
cross apply sys.dm_db_index_physical_stats( DB_ID(), idx.object_id, idx.index_id, NULL ,''LIMITED'') AS ips
where idx.[name] is not NULL
order by [fragmentation_percent] desc;'
EXEC sp_executesql @Command
FETCH NEXT FROM database_cursor INTO @DB_Name
END
CLOSE database_cursor
DEALLOCATE database_cursor
Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange