Commands / Get-sqmMissingIndexes

Get-sqmMissingIndexes Performance

Queries the SQL Server missing index DMVs for high-impact index recommendations, computes an ImpactScore, generates ready-to-run CREATE INDEX statements, and exports CSV and HTML reports. Excludes system databases automatically.

Execution Flow

START dbatools available? throw ERROR Invoke-DbaQuery: JOIN dm_db_missing_index_details / _groups / _group_stats WHERE database_id NOT IN (1,2,3,4) [excludes master/model/msdb/tempdb] ImpactScore = ROUND((seeks+scans)*avg_total_user_cost*(avg_user_impact/100.0),2) PS-side filter: -Database wildcards, -MinImpactScore, -MinSeeks, -Top foreach $row — New-sqmCreateIndexStatement (private helper) IX_<Table>_<ColShort>_<yyyyMMdd> (max 128 chars) + INCLUDE columns CSV export + ConvertTo-sqmHtmlReport → HTML Copy-sqmToCentralPath -Path @($csvFile) Return $results[] (ImpactScore desc, Top N) DONE

Synopsis

Reads the three missing-index DMVs (dm_db_missing_index_details, dm_db_missing_index_groups, dm_db_missing_index_group_stats) and ranks results by ImpactScore. A private helper New-sqmCreateIndexStatement generates a CREATE NONCLUSTERED INDEX statement for each recommendation, including INCLUDE columns and a date-stamped name. The CSV is also copied to the central path via Copy-sqmToCentralPath. The backward-compatible alias Build-sqmCreateIndexStatement maps to the same helper.

Requires dbatools. Index recommendations survive SQL Server restarts only until the DMV is cleared. ImpactScore is an estimate — always validate recommendations on a test system before applying. System databases are excluded in the SQL WHERE clause.

ImpactScore Formula

# Impact = estimated cumulative query cost savings
ImpactScore = ROUND(
    (user_seeks + user_scans)
    * avg_total_user_cost
    * (avg_user_impact / 100.0),
2)

Syntax

Get-sqmMissingIndexes
    [-SqlInstance <String>]
    [-SqlCredential <PSCredential>]
    [-Database <String[]>]         # wildcards; PS-side filter
    [-MinImpactScore <Double>]     # default 10
    [-MinSeeks <Int>]              # default 50
    [-Top <Int>]                    # default 50
    [-OutputPath <String>]
    [-EnableException]

Parameters

ParameterTypeDefaultDescription
-SqlInstanceString$env:COMPUTERNAMESQL Server instance to query.
-SqlCredentialPSCredentialSQL connection credential.
-DatabaseString[]all user DBsWildcard filter applied after query. Example: @('Sales*','HR').
-MinImpactScoreDouble10Minimum computed ImpactScore to include a row.
-MinSeeksInt50Minimum combined user_seeks + user_scans count.
-TopInt50Maximum rows to return after scoring and filtering.
-OutputPathStringGet-sqmConfig 'OutputPath'Directory for CSV and HTML report files.
-EnableExceptionSwitchfalseThrow terminating exceptions.

Return Value

PropertyDescription
DatabaseNameDatabase containing the table.
TableNameSchema-qualified table name.
EqualityColumnsColumns referenced in equality predicates.
InequalityColumnsColumns referenced in range predicates.
IncludedColumnsColumns needed for covering the query (SELECT list).
ImpactScoreComputed impact estimate (higher = more beneficial).
UserSeeks / UserScansQuery execution counts that triggered this recommendation.
CreateIndexStatementReady-to-run CREATE NONCLUSTERED INDEX T-SQL.

Examples

Example 1 — Top 20 high-impact indexes, local instance

Get-sqmMissingIndexes -Top 20

Example 2 — Filter to specific database, higher thresholds

Get-sqmMissingIndexes -SqlInstance "SQL01" -Database "Sales" -MinImpactScore 100 -MinSeeks 200

Example 3 — Export CREATE INDEX scripts to file

Get-sqmMissingIndexes | Select-Object CreateIndexStatement | Out-File "create_indexes.sql"