Skip to content

Commit 1630a5b

Browse files
Merge pull request #745 from erikdarlingdata/feature/sp-quickie-cache
Add sp_QuickieCache
2 parents a407c97 + 695b546 commit 1630a5b

3 files changed

Lines changed: 2073 additions & 0 deletions

File tree

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- [sp_HumanEvents](#human-events): Use Extended Events to track down various query performance issues
2626
- [sp_HumanEventsBlockViewer](#human-events-block-viewer): Analyze the blocked process report
2727
- [sp_QuickieStore](#quickie-store): The fastest and most configurable way to navigate Query Store data
28+
- [sp_QuickieCache](#quickie-cache): High-impact query detection from the plan cache using Pareto analysis
2829
- [sp_QueryReproBuilder](#query-repro-builder): Generate executable reproduction scripts from Query Store data
2930
- [sp_HealthParser](#health-parser): Pull all the performance-related data from the system health Extended Event
3031
- [sp_LogHunter](#log-hunter): Get all of the worst stuff out of your error log
@@ -329,6 +330,53 @@ Current valid parameter details:
329330
| @version_date | datetime | OUTPUT; for support | none; OUTPUT | none; OUTPUT |
330331

331332

333+
[*Back to top*](#navigatory)
334+
335+
## Quickie Cache
336+
337+
The plan cache companion to sp_QuickieStore. While QuickieStore digs into Query Store data, QuickieCache uses the same Pareto (80/20) analysis approach against the plan cache DMVs.
338+
339+
It aggregates data from `sys.dm_exec_query_stats`, `sys.dm_exec_procedure_stats`, `sys.dm_exec_function_stats`, and `sys.dm_exec_trigger_stats`, then scores queries across 7 resource dimensions (CPU, duration, reads, writes, memory grants, spills, executions) using `PERCENT_RANK`. Only the vital few queries with disproportionate resource consumption are surfaced.
340+
341+
Results come in three result sets:
342+
* **Plan cache health findings**: plan age distribution, single-use plan bloat, duplicate plan detection, USERSTORE_TOKENPERM pressure
343+
* **High-impact queries**: Pareto-scored queries with impact scores, resource shares, and diagnostic signals (parameter sniffing, plan instability, wasteful grants, wait-bound queries, etc.)
344+
* **Workload profile summary**: overall concentration analysis with tuning recommendations
345+
346+
Requires SQL Server 2016 SP1+ for full memory grant and spill analysis.
347+
348+
Current valid parameter details:
349+
350+
| parameter_name | data_type | description | valid_inputs | defaults |
351+
|-----------------------------|--------------|------------------------------------------------------------------------------------------------------|------------------------------------------|------------|
352+
| @top | integer | candidates per metric dimension before dedup | a positive integer | 10 |
353+
| @database_name | sysname | filter to a specific database | a valid database name | NULL |
354+
| @start_date | datetime | only include plans created after this date | a valid datetime | NULL |
355+
| @end_date | datetime | only include plans created before this date | a valid datetime | NULL |
356+
| @minimum_execution_count | bigint | minimum execution count to include a query | a positive integer | 2 |
357+
| @ignore_system_databases | bit | exclude system databases (master, model, msdb, tempdb) | 0 or 1 | 1 |
358+
| @impact_threshold | decimal(3,2) | minimum impact_score (0.00-1.00) to surface in results | 0.00 to 1.00 | 0.50 |
359+
| @debug | bit | print diagnostic information | 0 or 1 | 0 |
360+
| @help | bit | display parameter help | 0 or 1 | 0 |
361+
362+
```sql
363+
-- Basic execution
364+
EXECUTE dbo.sp_QuickieCache;
365+
366+
-- Focus on a specific database
367+
EXECUTE dbo.sp_QuickieCache
368+
@database_name = N'YourDatabase';
369+
370+
-- Only plans created today
371+
EXECUTE dbo.sp_QuickieCache
372+
@start_date = '20260403';
373+
374+
-- Lower the threshold to surface more queries
375+
EXECUTE dbo.sp_QuickieCache
376+
@impact_threshold = 0.25,
377+
@top = 20;
378+
```
379+
332380
[*Back to top*](#navigatory)
333381

334382
## Query Repro Builder

sp_QuickieCache/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<img src="https://erikdarling.com/wp-content/uploads/2025/08/darling-data-logo_RGB.jpg" width="300px" />
2+
3+
# sp_QuickieCache
4+
5+
The plan cache companion to sp_QuickieStore.
6+
7+
While QuickieStore digs into Query Store data, QuickieCache uses the same Pareto (80/20) analysis approach against the plan cache DMVs to find the vital few queries consuming disproportionate resources.
8+
9+
## How It Works
10+
11+
1. **Collects** data from all four plan cache stat DMVs (`dm_exec_query_stats`, `dm_exec_procedure_stats`, `dm_exec_function_stats`, `dm_exec_trigger_stats`)
12+
2. **Selects candidates** by taking the top N queries per metric dimension (CPU, duration, reads, writes, memory grants, spills, executions) and deduplicating
13+
3. **Scores** each candidate with `PERCENT_RANK` across all 7 dimensions, only counting dimensions where the query consumes >= 0.1% of the total
14+
4. **Surfaces** queries with an `impact_score` above the threshold, along with diagnostic signals
15+
16+
## Result Sets
17+
18+
1. **Plan cache health findings**: plan age distribution, single-use plan bloat per database, duplicate plan detection per database, USERSTORE_TOKENPERM memory pressure
19+
2. **High-impact queries**: Pareto-scored queries with resource shares and diagnostics
20+
3. **Workload profile summary**: concentration analysis (Concentrated / Moderate / Flat) with recommendations
21+
22+
## Diagnostics Detected
23+
24+
* Parameter sniffing (CPU and reads variance > 30% from average)
25+
* Plan instability (multiple cached plans for the same query)
26+
* Wait-bound queries (duration >> CPU)
27+
* Wasteful memory grants (< 10% utilization)
28+
* TempDB spills
29+
* Row count variance
30+
* Rare but expensive queries (few executions, high resource share)
31+
* High frequency queries (> 100 executions/minute)
32+
33+
## Parameters
34+
35+
| parameter_name | data_type | description | default |
36+
|---|---|---|---|
37+
| @top | integer | candidates per metric dimension before dedup | 10 |
38+
| @database_name | sysname | filter to a specific database | NULL |
39+
| @start_date | datetime | only include plans created after this date | NULL |
40+
| @end_date | datetime | only include plans created before this date | NULL |
41+
| @minimum_execution_count | bigint | minimum execution count to include a query | 2 |
42+
| @ignore_system_databases | bit | exclude system databases | 1 |
43+
| @impact_threshold | decimal(3,2) | minimum impact_score to surface | 0.50 |
44+
| @debug | bit | print diagnostic information | 0 |
45+
| @help | bit | display parameter help | 0 |
46+
47+
## Examples
48+
49+
```sql
50+
-- Basic execution
51+
EXECUTE dbo.sp_QuickieCache;
52+
53+
-- Focus on a specific database
54+
EXECUTE dbo.sp_QuickieCache
55+
@database_name = N'YourDatabase';
56+
57+
-- Only plans created today
58+
EXECUTE dbo.sp_QuickieCache
59+
@start_date = '20260403';
60+
61+
-- Lower the threshold to surface more queries
62+
EXECUTE dbo.sp_QuickieCache
63+
@impact_threshold = 0.25,
64+
@top = 20;
65+
66+
-- Filter to a specific time window
67+
EXECUTE dbo.sp_QuickieCache
68+
@start_date = '20260401',
69+
@end_date = '20260402';
70+
```
71+
72+
## Requirements
73+
74+
* SQL Server 2016 SP1+ for full memory grant and spill analysis
75+
* Older versions will work but with reduced metric coverage
76+
77+
## Resources
78+
* [sp_QuickieStore](https://github.com/erikdarlingdata/DarlingData/tree/main/sp_QuickieStore) - the Query Store companion
79+
* [Blog](https://www.erikdarling.com)

0 commit comments

Comments
 (0)