This just simply executes the following sql in each database for a server:
SELECT @@SERVERNAME AS ServerName, DB_NAME() AS DatabaseName, OBJECT_NAME(a.OBJECT_ID) AS TableName, COALESCE(name, 'object with no clustered index') AS IndexName, type_desc AS IndexType, user_seeks as IndexSeeks, CASE user_seeks WHEN 0 THEN 0 ELSE CONVERT(NUMERIC(10,2),user_seeks*1.0 /(user_scans + user_seeks) * 100.0) END AS IndexSeekPercentage, user_scans as IndexScans, CASE user_scans WHEN 0 THEN 0 ELSE CONVERT(NUMERIC(10,2), user_scans*1.0 /(user_scans + user_seeks) * 100.0) END AS IndexScanPercentage, user_lookups as BookMarkLookups, DATEDIFF ( dd , (SELECT login_time FROM master..sysprocesses WHERE spid = 1) , getdate()) NumDaysNotUsed FROM sys.dm_db_index_usage_stats a INNER JOIN sys.indexes b ON a.index_id = b.index_id AND a.object_id = b.object_id WHERE database_id = db_id() AND type_desc != 'HEAP' ORDER BY TableName
I can’t really remember where I got the sql code from to give proper attribution.
Here is the powershell script that executes this sql on a per-database level. Nothing special going on here, just a quick script in case you need it. It just outputs it to a gridview right now, but you can change it to write to file if you like. Use at your own risk.
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum")
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
$indexCmd = "
SELECT
@@SERVERNAME AS ServerName,
DB_NAME() AS DatabaseName,
OBJECT_NAME(a.OBJECT_ID) AS TableName,
COALESCE(name, 'object with no clustered index') AS IndexName,
type_desc AS IndexType,
user_seeks as IndexSeeks,
CASE user_seeks WHEN 0 THEN 0
ELSE CONVERT(NUMERIC(10,2),user_seeks*1.0 /(user_scans + user_seeks) * 100.0) END AS IndexSeekPercentage,
user_scans as IndexScans,
CASE user_scans WHEN 0 THEN 0
ELSE CONVERT(NUMERIC(10,2), user_scans*1.0 /(user_scans + user_seeks) * 100.0) END AS IndexScanPercentage,
user_lookups as BookMarkLookups,
DATEDIFF ( dd , (SELECT login_time FROM master..sysprocesses WHERE spid = 1) , getdate()) NumDaysNotUsed
FROM sys.dm_db_index_usage_stats a
INNER JOIN sys.indexes b ON a.index_id = b.index_id
AND a.object_id = b.object_id
WHERE
database_id = db_id()
AND type_desc != 'HEAP'
ORDER BY TableName
"
$serverName = 'ServerName'
$serverName | %{
$srvName = $_
$srvConn = New-Object "Microsoft.SqlServer.Management.Common.ServerConnection"
$srvConn.ServerInstance = $_
$srv = New-Object Microsoft.SqlServer.Management.Smo.Server $srvConn
[System.Data.DataTable]$dataTable = New-Object('system.Data.DataTable')
[System.Data.SqlClient.SqlCommand]$cmd = New-Object('system.data.sqlclient.sqlcommand')
[System.Data.SqlClient.SqlConnection]$c = New-Object('system.data.sqlclient.sqlconnection')
$dbs = $srv.Databases | where{-not $_.IsSystemObject}
$dbs | %{
$c.connectionstring = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=$($_.Name);Data Source=$srvName"
$c.open();
$cmd.Connection = $c;
$cmd.CommandType = [System.Data.CommandType]::Text
$cmd.commandText = $indexCmd
$dr = $cmd.ExecuteReader()
$dataTable.load($dr);
$c.Close();
}
}
$dataTable | Out-GridView
Leave a comment