SQL Server health review

SQL Server health review

Contoso Group (sample data)

Prepared by BPS

2servers reviewed
4urgent problems to talk through
24problems to plan

Use the right and left arrow keys to move between pages. Press G for a list of pages, N for presenter notes, F for full screen.

The review in one picture

6 urgent, 43 to plan, across 2 servers

121findings6Urgent43To plan72Worth knowing

Urgent means act soon. To plan means schedule it. Worth knowing is for awareness.

What good looks like
No urgent items. Anything to plan is on a dated list with an owner.

Server by server, area by area

Where the problems are

Data protectionAvailabilityCapacitySecurityPerformanceOperationssqlapp012urgent1to plan2urgent8to plan3to plan4to plansqlprd012urgent2to plan2to plan8to plan1to plan6to plan

Each box shows how many findings are in that area for that server. Red boxes show the number of urgent ones; amber boxes have nothing urgent and show how many to plan; grey boxes show items for awareness only; a green tick means nothing found. Most urgent items: sqlapp01.

What good looks like
Every box is a green tick, or amber at most, with nothing urgent.

Progress

0 fixed or gone, 0 new since the last review

ServerLast runChangeNewFixed or gone
sqlapp012026-10-23 15:003→3 urgent
20→20 to plan
Nothing newNothing fixed
sqlprd012026-10-23 14:401→1 urgent
22→22 to plan
Nothing newNothing fixed

Good news first

What is working well

SecurityThe sa login is disabled. (every server)
xp_cmdshell is off. (every server)
Operations and monitoringBackup compression is on by default. (every server)
The scheduled-job service (SQL Server Agent) is running. (every server)

At a glance

What is not in good shape

sqlapp01SQL Server 2019: extended support until Jan 20304 urgent21 to plan
sqlprd01SQL Server 2019: extended support until Jan 20302 urgent22 to plan
What good looks like
Each server shows no urgent items and a short list to plan.

How the servers are connected

2 servers, 2 availability groups

Network 10.50.25.0/24sqlapp01sqlprd01appagAgListener 10.50.18.109PprimaryScan lag · readablefinagFinCluster 10.50.25.150Scan lag · readableprimary copysecondary copywaits = primary waits for the copy · can lag = copy may be a little behind

Each row is an availability group: one primary copy of the data (P) and secondary copies (S) kept in step on the other servers. This page shows how the servers are connected; the problems found are on the pages that follow.

What good looks like
Every availability group has a primary and healthy secondary copies, on more than one network or site.

The big three

Memory, disk space and processor

MemoryDisk spaceProcessor (last 4 hours)sqlapp0185%memory in use · page life 3,689 s9% freetightest drive E: of 24%average · peak 19% · last 256 minsqlprd0190%memory in use · page life 1,261 s15% freetightest drive H: of 541%average · peak 81% · last 256 min

Red = needs attention now, amber = watch, green = fine. Memory pressure is judged on page life expectancy as well as how full the memory is.

What good looks like
Memory is not under pressure, every drive has at least 20% free, and processors are not constantly busy.

How the servers are set up

Every server runs Enterprise Edition

Evidence
sqlapp01Enterprise (core licensing)15.0.4500.28 processors47 GB set aside for SQL Server
sqlprd01Enterprise (core licensing)15.0.4500.216 processors109 GB set aside for SQL Server
What this tells us
  • Availability groups need it. appag keeps 6 copies (the basic group on Standard allows only 2); appag lets the secondary copies be read (not possible on Standard); finag keeps 4 copies (the basic group on Standard allows only 2); finag lets the secondary copies be read (not possible on Standard). Every server that holds a copy has to be Enterprise.
  • Server size is not the reason. Every server is within what Standard allows (24 processors and 128 GB of memory). The largest has 16 processors and 109 GB set aside for SQL Server.
  • Other features: compression, partitioning, encryption and the like were not checked in this run. A new check lists them on the next run.
Why it matters
Enterprise licences cost several times more per core than Standard. It is worth confirming that every server needs the extra features it is paying for.
What good looks like
Every server runs the edition it needs.

How the servers are set up

Enterprise is needed on every server

sqlapp01sqlprd01appag: more than 2 copiesEnterpriseEnterpriseappag: readable secondary copiesEnterpriseEnterprisefinag: more than 2 copiesEnterprise–finag: readable secondary copiesEnterprise–Needs Enterprise?YesYes

Based on the availability group design only. The feature check (compression, partitioning, encryption and more) was not part of this run.

What good looks like
Each Enterprise licence is used for a feature the business needs.

How the servers are set up

Availability group appag

Evidence

6 copies of AppDb; primary: sqlprd01

ServerRoleUpdatesFailoverReadableNetwork
sqlprd01Primary–ManualYes10.50.25.0/24
sqlapp01SecondaryDoes not wait (can lag)ManualYes10.50.25.0/24
sqlapp02 (not in this review)SecondaryDoes not wait (can lag)ManualYes10.50.25.0/24
sqlapp03 (not in this review)SecondaryDoes not wait (can lag)ManualYes10.50.25.0/24
sqldw01 (not in this review)SecondaryDoes not wait (can lag)ManualYes10.50.18.0/24
sqlrpt01 (not in this review)SecondaryDoes not wait (can lag)ManualYes10.50.25.0/24
What it means
  • Every secondary copy is updated without waiting, so it can be a little behind. If the primary failed suddenly, the most recent changes could be lost.
  • Failover is manual. Nothing moves the primary role by itself; someone has to do it, so the service stays down until they do.
  • The secondary copies can be read. Reports and other read-only work can run there and take load off the primary.
  • The copies sit on 2 networks (10.50.18.0/24, 10.50.25.0/24), which suggests a copy at another site for disaster recovery.
  • It runs on the Windows cluster ProdCluster with 6 servers and no witness.
What good looks like
All copies are healthy, keeping up, and each is placed where the design needs it.

How the servers are set up

Availability group finag

Evidence

4 copies of FinanceDb; primary: sqlapp01

ServerRoleUpdatesFailoverReadableNetwork
sqlapp01SecondaryDoes not wait (can lag)ManualYes10.50.25.0/24
sqlapp03 (not in this review)SecondaryDoes not wait (can lag)ManualYes10.50.25.0/24
sqlfin01 (not in this review)SecondaryWaits for the copyManualYes
sqlrpt01 (not in this review)SecondaryDoes not wait (can lag)ManualYes10.50.25.0/24
What it means
  • At least one secondary waits for the primary, so nothing it has confirmed is lost if the primary fails.
  • Failover is manual. Nothing moves the primary role by itself; someone has to do it, so the service stays down until they do.
  • The secondary copies can be read. Reports and other read-only work can run there and take load off the primary.
  • The group has no cluster behind it, so there is no automatic failover and no cluster to keep it running.
What good looks like
All copies are healthy, keeping up, and each is placed where the design needs it.

How the servers are set up

1 (50%) availability groups need attention · 2 servers

appagProdCluster · primary sqlprd01 · 5 secondary copies: 0 sync, 5 async, 5 readable · listener AgListener · 1 databaseCopies5 (100%)healthyLongest lag0 sbehind the primaryFailoverManuala person must actTie-breakerNoneeven votesCopies match302differencesFailovers2last Oct 18Open findings3 to planavailabilityfinagcluster not reported · primary sqlapp01 · 4 secondary copies: 1 sync, 3 async, 4 readable · listener FinCluster · 1 databaseCopies4 (100%)healthyLongest lagn/anot reportedFailoverManuala person must actTie-breakern/avotes not reportedCopies matchn/aone server auditedFailovers0none recordedOpen findings1 to planavailability

The whole high-availability picture on one page, before the detail. Each tile is judged on this audit’s data: green is fine, amber is worth planning, red needs action soon, grey was not reported. The next pages explain each tile.

What good looks like
Every group is healthy, and each copy is in the state the design intends.

How the servers are set up

All 9 secondary copies are healthy and keeping up

appagall copies keeping up; 5 (100%) are asynchronous, so they can fall behind under loadsqlprd01primaryNot yet sent0 KBNot yet applied62 KBsqlapp01ASYNCREADABLE0 skeeping upNot yet sent0 KBNot yet applied76 KBsqlapp02ASYNCREADABLE0 skeeping upNot yet sent0 KBNot yet applied78 KBsqlapp03ASYNCREADABLE0 skeeping upNot yet sent0 KBNot yet applied54 KBsqldw01ASYNCREADABLE0 skeeping upNot yet sent0 KBNot yet applied78 KBsqlrpt01ASYNCREADABLE0 skeeping upfinagall copies keeping up; 3 (75%) are asynchronous, so they can fall behind under loadsqlapp01primaryNot yet sent0 KBNot yet applied14 KBsqlapp01ASYNCREADABLEnot reportedkeeping upNot yet sentnot reportedNot yet appliednot reportedsqlapp03ASYNCREADABLEnot reportedkeeping upNot yet sentnot reportedNot yet appliednot reportedsqlfin01SYNCREADABLEnot reportedkeeping upNot yet sentnot reportedNot yet appliednot reportedsqlrpt01ASYNCREADABLEnot reportedkeeping up

Taken when the audit ran. Solid arrow = the primary waits for the copy; dashed = it does not, so the copy can fall behind. Queues are the data still waiting to be sent to, or applied on, the copy. Red = unhealthy, suspended or over a minute behind.

What good looks like
Secondary copies keep up, with seconds or less of delay and nothing waiting to be sent.

How the servers are set up

1 (100%) clusters have no tie-breaker

ProdClusterNode Majority · carries appagNo tie-breakersqlapp01Secondary copy1sqlapp02Secondary copy1sqlapp03Secondary copy1sqldw01Secondary copy1sqlprd01Primary copy1sqlrpt01Secondary copy1No witnessa tie-breaker is missing6 votes in total. 4 must stay in contact for the cluster to stay up.majority: 4 (67%)Lose 1 serverKeeps runningLose 2 serversKeeps runningLose 3 serversStopsNetwork split 3 and 3Both halves stopWith a witness added (7 votes): a network split 4 and 3 keeps one side running.

Every server in the cluster holds a vote and the cluster stays up only while more than half of all votes can talk to each other. A witness is an extra vote that avoids a tie.

What good looks like
Every cluster has a tie-breaker, so it survives losing a server or a network split.

Data protection

3 (6%) databases need backup attention

recent full backuplate (over 2 days)overdue, missing or log backups missingsqlapp0136 fine362 needs attention22 (5%) need attentionsqlprd0110 fine101 needs attention11 (9%) need attention

One bar per server; every database is a share of the bar. Red databases have no full backup in the last 7 days, no log backup where one is needed, or log backups thrown away.

What good looks like
Every database has a full backup in the last 7 days, and log backups wherever the database needs them.

Storage

7 busy database files respond slowly

under 10 ms10 to 20 ms20 to 50 msover 50 mssqlapp01FinanceDb (ROWS, D:): 524 msJOB00001 (ROWS, D:): 123 msUser00054 (ROWS, D:): 95 msObj00004 (ROWS, D:): 35 msUser00056 (ROWS, D:): 34 msAppDb (ROWS, D:): 25 mscontoso_apps (ROWS, D:): 25 msDb00006 (ROWS, D:): 17 msJob00173 (ROWS, D:): 17 msJob00008 (ROWS, D:): 16 msjob00016 (ROWS, D:): 15 msDb00010 (ROWS, D:): 13 msObj00003 (ROWS, D:): 11 msDb00007 (ROWS, E:): 10 msmsdb (ROWS, D:): 8 msDB00003 (ROWS, D:): 8 msJOB00010 (ROWS, E:): 8 mstempdb (ROWS, D:): 6 msObj00005 (LOG, E:): 6 msFinanceDb (LOG, E:): 6 msDb00001 (ROWS, D:): 5 msAppDb (LOG, E:): 5 msObj00002 (ROWS, D:): 5 msDb00004 (ROWS, D:): 5 mstempdb (ROWS, D:): 5 msDb00011 (ROWS, D:): 5 mstempdb (ROWS, D:): 4 mstempdb (ROWS, D:): 4 msObj00004 (LOG, E:): 4 msaudIT (ROWS, D:): 4 mstempdb (ROWS, D:): 4 mstempdb (ROWS, D:): 4 mstempdb (ROWS, D:): 4 mstempdb (ROWS, D:): 4 msJob00047 (ROWS, D:): 4 msJob00008 (LOG, E:): 4 msDb00005 (LOG, E:): 4 msJob00031 (ROWS, D:): 4 msDb00005 (ROWS, D:): 3 msDb00001 (LOG, E:): 3 msDb00012 (ROWS, D:): 3 msAutomation (ROWS, D:): 3 msaudIT (LOG, E:): 3 msJOB00010 (LOG, E:): 3 msDb00007 (LOG, E:): 3 msUser00027 (ROWS, D:): 2 msObj00005 (ROWS, D:): 2 msdev_apps (ROWS, D:): 2 mstempdb (LOG, E:): 2 msJob00173 (LOG, E:): 2 msDB00003 (LOG, E:): 1 msjob00016 (LOG, E:): 1 msmaster (LOG, D:): 1 msmsdb (LOG, D:): 1 ms7 slow of 54sqlprd01Db00014 (ROWS, F:): 13 mstempdb (LOG, D:): 6 msmsdb (ROWS, C:): 6 msAppDb (ROWS, F:): 6 msdb00001 (ROWS, F:): 5 msDb00014 (LOG, E:): 4 msAppDb (LOG, E:): 4 msDb00002 (ROWS, H:): 4 msdb00001 (LOG, E:): 3 msAppDb_datastore (ROWS, F:): 3 msAppDb_datastore (LOG, E:): 3 mstempdb (ROWS, D:): 2 mstempdb (ROWS, D:): 2 mstempdb (ROWS, D:): 2 mstempdb (ROWS, D:): 2 mstempdb (ROWS, D:): 2 mstempdb (ROWS, D:): 2 mstempdb (ROWS, D:): 2 mstempdb (ROWS, D:): 2 msmsdb (LOG, C:): 2 msDb00002 (LOG, E:): 2 msbold_services_dev (ROWS, F:): 2 msbold_services_dev (LOG, E:): 2 msObj00007_440 (LOG, E:): 2 msObj00007_440 (ROWS, F:): 2 msmaster (ROWS, C:): 2 msmaster (LOG, C:): 1 ms0 slow of 27

One square per busy database file, worst first. Response time since the last restart; under 20 ms is good for data files.

What good looks like
Busy database files respond in under 20 ms.

Capacity

2,460 GB of data in 41 databases

Db00002876GB · one serverFinanceDb806GB · one serverAppDb537GB · copies on 2 serversDb0000160GB · copies on 2 serversJOB0001033GB · one serverDb0000729GB · one servercontoso_apps21GB · one serverJob0017317GB · one serverObj0000414GB · one serverDb0001412GB · one serverAll other databases (31)54GB

Each database is counted once, even where copies sit on several servers (availability groups). Disk used on each server, copies included: sqlapp01 1,561 GB, sqlprd01 1,453 GB.

What good looks like
Data growth is understood, and there is room for at least a year of growth.

Indexes

Indexes to add

DatabaseTable (columns)Why
AppDb[AppDb].[dbo].[Obj00527]The optimizer asked for it 14,174 times; estimated 47% faster
AppDb[AppDb].[dbo].[Obj00616_obj00507_usage]The optimizer asked for it 242,802 times; estimated 100% faster
AppDb[AppDb].[dbo].[Obj00793]The optimizer asked for it 584,112 times; estimated 22% faster
AppDb[AppDb].[dbo].[obj00794]The optimizer asked for it 79,793 times; estimated 76% faster
AppDb[AppDb].[dbo].[Obj00793]The optimizer asked for it 457,541 times; estimated 19% faster
AppDb[AppDb].[dbo].[Obj00793]The optimizer asked for it 457,541 times; estimated 18% faster
AppDb[AppDb].[dbo].[Obj00793]The optimizer asked for it 457,541 times; estimated 18% faster
AppDb[AppDb].[dbo].[Obj00793]The optimizer asked for it 457,541 times; estimated 17% faster
AppDb[AppDb].[dbo].[Obj00795]The optimizer asked for it 547,145 times; estimated 14% faster
AppDb[AppDb].[dbo].[obj00512]The optimizer asked for it 32,058 times; estimated 48% faster

10 suggested. The report holds each one with a script to copy.

What good looks like
The queries that matter have indexes that support them.

Indexes

1 (100%) index maintenance jobs are not running

ServerJobState
sqlprd01IndexOptimize - USER_DATABASESNo schedule, not running

Statistics age on the larger databases:

  • sqlprd01, AppDb_datastore: 755 (97%) statistics are over 90 days old (97%)
  • sqlapp01, dev_apps: 1,658 (87%) statistics are over 90 days old (87%)
  • sqlapp01, contoso_apps: 971 (83%) statistics are over 90 days old (83%)
  • sqlprd01, Obj00007_440: 2,546 (66%) statistics are over 90 days old (66%)
  • sqlapp01, AppDb: 5,011 (39%) statistics are over 90 days old (39%)

A job with no schedule may be started by something else; this check only sees Agent schedules and the last 7 days of runs.

What good looks like
Index maintenance runs on a schedule and succeeds every time.

UrgentCapacity and storage · 2 servers

Disk drives running out of space

Evidence
sqlapp01Drive E:\ is nearly full (9.4% free)
sqlprd01Drive H:\ is getting full (14.5% free)
Why it matters
When a drive fills, databases stop accepting changes and applications fail.
What good looks like
At least 20% free on every drive (urgent below 10%).

UrgentData protection · 2 servers

Transaction log backups are being thrown away

Evidence
sqlapp01FinanceDb – SQL Server's own records show the transaction log of FinanceDb was “ba
AppDb – SQL Server's own records show the transaction log of AppDb was “backed
sqlprd01AppDb: log backups were sent to NUL
Why it matters
These databases can only be restored to their last full backup, not to a recent moment, and the log can grow without limit.
What good looks like
Log backups go to real backup files every 15 to 60 minutes for every database in FULL recovery.

UrgentData protection · 1 server

Backup jobs that fail regularly

Evidence
sqlprd01Backup job “Job00058.job00124_bk” fails often (60.1% success)
Backup job “Job00058.AppDb_backup” fails often (90.0% success)
Why it matters
A backup that fails quietly leaves less protection than anyone thinks.
What good looks like
Backup jobs succeed every time, and any failure is looked at the same day.

UrgentCapacity and storage · 1 server

Slow disk response

Evidence
sqlapp014 database file(s) have slow disk response
Why it matters
Slow storage makes every application that uses these databases slower.
What good looks like
Average read and write under 20 ms for data files, and under 10 ms for log files.

PlanAvailability · 2 servers

Cluster could split in two with no tie-breaker

Evidence
sqlapp01Cluster has 6 voting nodes and no witness
sqlprd01Cluster has 6 voting nodes and no witness
Why it matters
If the network between the servers is cut, neither side may know it should stay up.
What good looks like
A witness (file share, disk or cloud) so the cluster can always reach a majority.

PlanSecurity · 2 servers

Database users that could map to the wrong login after a restore

Evidence
sqlapp0114 database user(s) share a name with a different server login
sqlprd011 database user(s) share a name with a different server login
Why it matters
Someone could silently get another person’s access.
What good looks like
A database user and the server login with the same name are the same identity.

PlanData protection · 2 servers

Databases never checked for corruption

Evidence
sqlapp0110 user database(s) have no successful consistency check (CHECKDB) in the last 14 days
sqlprd018 user database(s) have no successful consistency check (CHECKDB) in the last 14 days
Why it matters
Corruption found late may already be in every backup.
What good looks like
A successful consistency check (CHECKDB) at least weekly for every database.

PlanSecurity · 2 servers

Linked servers that sign in with a stored or powerful login

Evidence
sqlapp0119 linked server mapping(s) need review
sqlprd0112 linked server mapping(s) need review
Why it matters
A weak link to another server can expose both servers.
What good looks like
Each linked server uses the caller’s own identity or a minimal-rights account, and never sa.

PlanData protection · 2 servers

Long gaps between backups

Evidence
sqlapp012 database(s) have a worst-case data loss window of more than 24 hours
sqlprd013 database(s) have a worst-case data loss window of more than 24 hours
Why it matters
After a failure, up to this much recent work could be lost.
What good looks like
No gap between backups longer than the agreed data-loss window (for example 1 hour).

PlanSecurity · 2 servers

Many accounts with full administrator rights

Evidence
sqlapp0114 enabled logins have full administrator (sysadmin) rights
sqlprd0118 enabled logins have full administrator (sysadmin) rights
Why it matters
Every such account can read, change or delete everything.
What good looks like
Only the few accounts that truly need full control, named people or managed service accounts.

PlanOperations and monitoring · 2 servers

Nobody is warned when SQL Server reports a serious error

Evidence
sqlapp01No SQL Agent alerts for corruption (errors 823, 824, 825)
No SQL Agent alerts for severity 19-25 errors
sqlprd01No SQL Agent alerts for corruption (errors 823, 824, 825)
No SQL Agent alerts for severity 19-25 errors
Why it matters
Serious problems can go unnoticed until users complain.
What good looks like
Alerts for severity 19 to 25 and errors 823, 824 and 825 reach an operator who reads them.

PlanSecurity · 2 servers

Optional server features switched on that widen the attack surface

Evidence
sqlapp012 server feature(s) widen the attack surface
sqlprd014 server feature(s) widen the attack surface
Why it matters
Each one is another way in if the server is attacked.
What good looks like
Features such as xp_cmdshell, OLE Automation, ad hoc queries and cross-database chaining are off unless an application needs them.

PlanPerformance · 2 servers

Out-of-date query statistics

Evidence
sqlapp0110,055 (22%) statistics are older than 90 days; 100 have over 100,000 changes since the last update
sqlprd019,464 (43%) statistics are older than 90 days; 68 have over 100,000 changes since the last update
Why it matters
Queries can pick slow plans.
What good looks like
Fewer than a quarter of the statistics older than 90 days, refreshed by a regular job.

PlanSecurity · 2 servers

Permissions granted to every user of a database (the public role)

Evidence
sqlapp01Permissions are granted to the public role in 15 database(s)
sqlprd01Permissions are granted to the public role in 3 database(s)
Why it matters
Everyone with access to the database gets them.
What good looks like
No object or column permissions are granted to public; they go to named roles.

PlanSecurity · 2 servers

SQL logins that ignore the password policy

Evidence
sqlapp0131 SQL login(s) do not enforce the password policy
sqlprd0125 SQL login(s) do not enforce the password policy
Why it matters
Their passwords never expire and can be weak.
What good looks like
Password policy is enforced for every SQL login.

PlanOperations and monitoring · 2 servers

Scheduled jobs that fail without telling anyone

Evidence
sqlapp019 (31%) enabled Agent jobs send no email at all
sqlprd0122 (25%) enabled Agent jobs send no email at all
Why it matters
Failures can go unnoticed for days.
What good looks like
Every important job notifies an operator when it fails.

PlanCapacity and storage · 2 servers

Very large, mostly empty transaction logs

Evidence
sqlapp01FinanceDb – Log size 410 GB, 100% free, against 396 GB of data
AppDb – Log size 231 GB, 100% free, against 306 GB of data
sqlprd01AppDb: the transaction log is 231 GB and almost empty
Why it matters
They hold disk space that other databases may need.
What good looks like
Each log is close to its normal working size.

PlanSecurity · 2 servers

Weak or expired encryption keys and certificates

Evidence
sqlapp012 encryption key or certificate problem(s)
sqlprd012 encryption key or certificate problem(s)
Why it matters
Encrypted data may not be as protected as assumed.
What good looks like
AES keys, certificate keys of 2048 bits or more, and nothing expired.

PlanSecurity · 1 server

Accounts with very powerful permissions in databases

Evidence
sqlapp018 high-impact permission grant(s) to users or roles
Why it matters
Mistakes or misuse by those accounts have a large effect.
What good looks like
Powerful permissions (CONTROL, ALTER, IMPERSONATE) are held only by named administrators.

PlanOperations and monitoring · 1 server

Database Mail is reporting errors

Evidence
sqlprd01Database Mail reported 10 error(s) in the last 7 days
Why it matters
Alert and job emails may not be arriving.
What good looks like
The mail profile works and shows no errors.

PlanSecurity · 1 server

Database settings that bypass normal security checks

Evidence
sqlprd01Trustworthy is ON (only msdb should have it) in 1 database(s)
Why it matters
They let code in one database act with the rights of another.
What good looks like
Trustworthy is off except in msdb, and cross-database chaining is off for user databases.

PlanOperations and monitoring · 1 server

Database text-comparison settings differ from the server

Evidence
sqlapp01Collation differs from the server and tempdb; string comparisons with temp tables can fail (3 database(s))
Why it matters
Queries that join to temporary data can fail.
What good looks like
User databases use the same collation as the server.

PlanPerformance · 1 server

Query Store has stopped recording

Evidence
sqlapp01Query Store is read-only in 2 database(s)
Why it matters
No history is kept to explain slow queries.
What good looks like
Query Store is on and read-write for the important databases.

PlanAvailability · 1 server

Repeated connection time-outs between servers in the group

Evidence
sqlprd01Connections to 3 secondary replica(s) time out repeatedly (15 times in the log)
Why it matters
The standby copies can fall behind or disconnect.
What good looks like
No repeated time-outs between the servers in the group.

PlanOperations and monitoring · 1 server

Scheduled jobs that failed this week

Evidence
sqlprd014 Agent job(s) failed in the last 7 days
Why it matters
Work they should be doing is not happening.
What good looks like
Every scheduled job succeeds, and any failure is looked at the same day.

PlanOperations and monitoring · 1 server

Scheduled jobs that often fail

Evidence
sqlprd016 other Agent job(s) succeed less than 95% of the time
Why it matters
They need attention before they stop working altogether.
What good looks like
Every scheduled job succeeds, and any failure is looked at the same day.

PlanPerformance · 1 server

The temporary database (tempdb) is not set up the recommended way

Evidence
sqlapp01tempdb configuration can be improved
Why it matters
It can slow every busy application.
What good looks like
Equal-size data files (up to 8, about one per processor), fixed growth steps, and not on the C: drive.

PlanCapacity and storage · 1 server

Transaction logs with far too many internal segments

Evidence
sqlapp011 transaction log(s) have a very high virtual log file count
Why it matters
Startup, restore and log backup are slower than they should be.
What good looks like
Under 1,000 virtual log files per log (under 500 is ideal).

The way forward

About 120 hours of effort, urgent items first

0 h30 h60 h90 h120 hDisk drives running out of space9.5 hSlow disk response9.5 hTransaction log backups are being thrown away5.5 hBackup jobs that fail regularly2.5 hRepeated connection time-outs between servers in t…11.5 hMany accounts with full administrator rights7.0 hDatabases never checked for corruption6.5 hNobody is warned when SQL Server reports a serious…4.5 hScheduled jobs that fail without telling anyone4.5 hOut-of-date query statistics4.5 hLinked servers that sign in with a stored or power…4.5 hPermissions granted to every user of a database (t…4.5 hLong gaps between backups4.0 hWeak or expired encryption keys and certificates4.0 h14 smaller items37.5 h

Hours per kind of problem, taken from the remediation estimate. Bars are laid end to end in the order the work would be done; the real plan can run items in parallel.

What good looks like
The urgent items are done first, with an owner and a date for each.

Results

Results: 0 measures improved

6 → 6Urgent findings
302 → 302Differences between replicas
Urgent findings66no changeFindings to plan4343no changeMissing indexes the optimizer asks for5050no changeStatistics over 90 days old (%)2929no changeIndex maintenance jobs not running11no changebeforeaftereach row has its own scale

Before: 2026-10-23_143259 (2026-10-23 14:40). After: the newest run (2026-10-23 15:00). A measure is improved only when the second run no longer shows the problem; it is not a prediction. Measures only one of the two runs could take are left out.

Results

Availability: 0 (0%) measures improved

Differences between replicas302302no changeClusters with no tie-breaker11no changeSecondary copies behind or unhealthy00no changeLongest lag (seconds)00no changebeforeaftereach row has its own scale

Same measures, taken from the second run.

Results

What was done about each recommendation

ActionWhereStatus
Add[AppDb].[dbo].[Obj00527]Still requested
Add[AppDb].[dbo].[Obj00616_obj00507_usage]Still requested
Add[AppDb].[dbo].[Obj00793]Still requested
Add[AppDb].[dbo].[obj00794]Still requested
Add[AppDb].[dbo].[Obj00793]Still requested
Add[AppDb].[dbo].[Obj00793]Still requested
Add[AppDb].[dbo].[Obj00793]Still requested
Add[AppDb].[dbo].[Obj00793]Still requested
Add[AppDb].[dbo].[Obj00795]Still requested
Add[AppDb].[dbo].[obj00512]Still requested

The plan

120 hours to fix what was found

The quote
WorkItemsBPS effort
Urgent items427 hours
Items to plan2493 hours
Total28120 hours
How we show the improvement
  • The main report is the before: it records where every server stands today.
  • When the work is done we run the same review again. The report then shows the after next to the before for each measure, so every improvement can be seen and checked.
  • Anything not yet fixed stays visible, so nothing is lost between rounds of work.
← → pages · G list · N notes · D details · F full screen