Skip to content

Commit 68a584a

Browse files
author
Tim Chapman
committed
added functionality to connect to query store or query_stats to extract data for rule analysis.
1 parent b7fa7ea commit 68a584a

36 files changed

Lines changed: 2629 additions & 51 deletions

.claude/settings.local.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(dotnet build:*)"
5+
]
6+
}
7+
}

.env.example

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# LLM Configuration for SQL Fixer
2+
# Copy this to .env at the repo root and fill in your values
3+
4+
# ==============================================================================
5+
# OPTION 1: Azure OpenAI with Keyless Authentication (RECOMMENDED)
6+
# ==============================================================================
7+
# LLM_AUTH_TYPE=credential
8+
# LLM_API_ENDPOINT=https://your-resource.openai.azure.com
9+
# LLM_MODEL=gpt-4o
10+
# LLM_API_VERSION=2025-01-01-preview
11+
12+
# ==============================================================================
13+
# OPTION 2: Azure OpenAI with API Key (Legacy)
14+
# ==============================================================================
15+
# LLM_AUTH_TYPE=apikey
16+
# LLM_API_ENDPOINT=https://your-resource.openai.azure.com
17+
# LLM_API_KEY=your-azure-api-key-here
18+
# LLM_MODEL=gpt-4o
19+
# LLM_API_VERSION=2025-01-01-preview
20+
21+
# ==============================================================================
22+
# OPTION 3: OpenAI Configuration
23+
# ==============================================================================
24+
# LLM_AUTH_TYPE=apikey
25+
# LLM_API_ENDPOINT=https://api.openai.com/v1/chat/completions
26+
# LLM_API_KEY=your-openai-api-key-here
27+
# LLM_MODEL=gpt-4
28+
29+
# ==============================================================================
30+
# OPTION 4: Other OpenAI-compatible APIs
31+
# ==============================================================================
32+
# LLM_AUTH_TYPE=apikey
33+
# LLM_API_ENDPOINT=https://your-custom-endpoint.com/v1/chat/completions
34+
# LLM_API_KEY=your-api-key
35+
# LLM_MODEL=your-model-name
36+
37+
# ==============================================================================
38+
# SQL Server Direct Analysis (optional)
39+
# ==============================================================================
40+
# When connection info is present, Query Store queries are pulled automatically.
41+
#
42+
43+
# SQL_SERVER_NAME=your-server.database.windows.net
44+
# SQL_SERVER_DATABASE=YourDatabase
45+
# SQL_SERVER_USER=sqluser # omit for Windows auth
46+
# SQL_SERVER_PASSWORD=yourpassword
47+
# SQL_TRUST_SERVER_CERTIFICATE=false

.github/copilot-agent.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,32 @@
8080
"Scan this directory for SQL violations",
8181
"What's wrong with this query?",
8282
"Analyze this execution plan"
83+
],
84+
"commands": [
85+
{
86+
"name": "setup",
87+
"description": "Check prerequisites and build the project",
88+
"instruction": "Follow instructions in .github/prompts/setup.prompt.md"
89+
},
90+
{
91+
"name": "extract-queries",
92+
"description": "Extract SQL queries from Query Store",
93+
"instruction": "Follow instructions in .github/prompts/extract-queries.prompt.md"
94+
},
95+
{
96+
"name": "extract-plans",
97+
"description": "Extract execution plans from Query Store",
98+
"instruction": "Follow instructions in .github/prompts/extract-plans.prompt.md"
99+
},
100+
{
101+
"name": "analyze-sql",
102+
"description": "Analyze SQL files in Analysis/input with auto-fix",
103+
"instruction": "Follow instructions in .github/prompts/analyze-sql.prompt.md"
104+
},
105+
{
106+
"name": "clean-workspace",
107+
"description": "Clean Analysis/output folder",
108+
"instruction": "Follow instructions in .github/prompts/clean-workspace.prompt.md"
109+
}
83110
]
84111
}

.github/copilot-instructions.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ cd SqlAnalyzer\bin\Release\net8.0
104104
### ✅ LLM-Powered Auto-Fix
105105
When user wants to automatically fix SQL violations:
106106
```powershell
107-
# Requires .env file with Azure OpenAI or OpenAI configuration
108-
.\SqlAnalyzer.exe --file "query.sql" --fix --env ".env"
107+
# Requires .env file with Azure OpenAI or OpenAI configuration at the repository root (same folder as Analyzer.sln)
108+
.\SqlAnalyzer.exe --file "query.sql" --fix
109109
```
110110

111111
## Project Structure Awareness
@@ -246,8 +246,7 @@ Already configured with:
246246
- Verify file has .sql, .dacpac, .sqlplan, or .xel extension
247247

248248
**Issue: "Azure OpenAI configuration missing"**
249-
- Create .env file with required variables
250-
- Pass .env path with --env parameter
249+
- Create .env file with required variables at the repository root
251250

252251
**Issue: "API not accessible"**
253252
- Check if API is running: `netstat -ano | findstr :5000`

.github/prompts/analyze-sql.prompt.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ tools: ['codebase', 'usages', 'vscodeAPI', 'think', 'problems', 'changes', 'test
88

99
Analyze SQL Server code for performance issues, security risks, and design problems using the SQL Analyzer tool.
1010

11+
**Related Commands:**
12+
- To extract queries from a live SQL Server database first, use: [extract-queries.prompt.md](file:///c%3A/Projects/Analyzer/.github/prompts/extract-queries.prompt.md)
13+
1114
## ⚠️ CRITICAL RULE: ABSOLUTELY NO OUTPUT UNTIL JSON FILES EXIST
1215

1316
**YOU MUST NOT SEND ANY MESSAGE TO THE CHAT WINDOW UNTIL:**

.github/prompts/auto-fix-sql.prompt.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ Review the violations to understand what will be fixed.
5353
Run the analyzer with `--fix` flag:
5454
```powershell
5555
cd SqlAnalyzer\bin\Release\net8.0
56-
.\SqlAnalyzer.exe --file "path\to\query.sql" --fix --env "..\..\..\..\..\.env"
56+
.\SqlAnalyzer.exe --file "path\to\query.sql" --fix
5757
```
5858

5959
Or use relative path:
6060
```powershell
61-
.\SqlAnalyzer.exe --file "query.sql" --fix --env ".env"
61+
.\SqlAnalyzer.exe --file "query.sql" --fix
6262
```
6363

6464
### STEP 3: Review the Output
@@ -173,7 +173,7 @@ To fix multiple files, use PowerShell:
173173
```powershell
174174
$files = Get-ChildItem -Path "C:\Scripts" -Filter *.sql -Recurse
175175
foreach ($file in $files) {
176-
.\SqlAnalyzer.exe --file $file.FullName --fix --env ".env"
176+
.\SqlAnalyzer.exe --file $file.FullName --fix
177177
}
178178
```
179179

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Clean Analysis Workspace
2+
3+
Delete all analysis reports from the Analysis/output folder to start fresh.
4+
5+
## Purpose
6+
7+
Removes generated JSON reports and log files from previous analysis runs. Useful when:
8+
- Starting a new analysis batch
9+
- Output folder has accumulated many old reports
10+
- Want to verify fresh analysis results
11+
- Preparing for a clean analysis run
12+
13+
## What Gets Deleted
14+
15+
From Analysis/output folder:
16+
- All *.json files (analysis reports)
17+
- All *.txt files (LLM fix logs)
18+
- Does NOT touch Analysis/input (your SQL files are safe)
19+
20+
## Workflow
21+
22+
### Run the Cleanup Script
23+
24+
```powershell
25+
.\scripts\clean-reports.ps1
26+
```
27+
28+
**Output:**
29+
```
30+
Deleted 5 report file(s) from C:\Projects\Analyzer\Analysis\output
31+
```
32+
33+
### Custom Path (optional)
34+
35+
Clean a different reports directory:
36+
```powershell
37+
.\scripts\clean-reports.ps1 -ReportsPath "C:\CustomPath\reports"
38+
```
39+
40+
## When to Use
41+
42+
**Before analysis:**
43+
- Clean slate for new batch of queries
44+
- Remove old reports that may cause confusion
45+
46+
**After reviewing:**
47+
- Archive important reports elsewhere first
48+
- Clean up to reduce clutter
49+
50+
## Safety Notes
51+
52+
**Safe operations:**
53+
- Only deletes files in Analysis/output
54+
- Analysis/input SQL files are never touched
55+
- Source code is never affected
56+
- .env file is never deleted
57+
58+
⚠️ **Important:**
59+
- Deleted files cannot be recovered
60+
- Archive any reports you want to keep before cleaning
61+
- Consider committing important results to version control first
62+
63+
## Next Steps
64+
65+
After cleaning:
66+
1. Extract fresh queries: Follow [extract-queries.prompt.md](file:///c%3A/Projects/Analyzer/.github/prompts/extract-queries.prompt.md)
67+
2. Analyze: Follow [analyze-sql.prompt.md](file:///c%3A/Projects/Analyzer/.github/prompts/analyze-sql.prompt.md)
68+
3. Review new reports in Analysis/output
69+
70+
## Reference
71+
72+
- Script location: [scripts/clean-reports.ps1](file:///c%3A/Projects/Analyzer/scripts/clean-reports.ps1)
73+
- Output folder: [Analysis/output](file:///c%3A/Projects/Analyzer/Analysis/output)
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Extract Execution Plans from Query Store
2+
3+
Pull execution plans from SQL Server Query Store for performance analysis.
4+
5+
## Purpose
6+
7+
Extracts actual execution plans (as XML) from Query Store and saves them as .sqlplan files.
8+
The SQL Analyzer can then analyze these plans for:
9+
- Expensive sort operations
10+
- Table/index scans
11+
- Missing indexes
12+
- High-cost operators
13+
- Implicit conversions
14+
15+
## Prerequisites
16+
17+
- SQL Server with Query Store enabled
18+
- Connection details in .env file or passed as parameters
19+
- Query Store must have captured queries
20+
21+
## Workflow
22+
23+
### Extract Execution Plans
24+
25+
**Default (top 50 plans by duration):**
26+
```powershell
27+
.\scripts\export-queries.ps1 -ExportPlans
28+
```
29+
30+
**By specific metric:**
31+
```powershell
32+
# Top plans by CPU
33+
.\scripts\export-queries.ps1 -ExportPlans -Top 20 -Metric cpu
34+
35+
# Top plans by logical reads
36+
.\scripts\export-queries.ps1 -ExportPlans -Top 30 -Metric reads
37+
38+
# Top plans by execution count
39+
.\scripts\export-queries.ps1 -ExportPlans -Top 25 -Metric executions
40+
```
41+
42+
**With custom lookback window:**
43+
```powershell
44+
# Last 4 hours
45+
.\scripts\export-queries.ps1 -ExportPlans -LookbackMinutes 240
46+
47+
# Last 7 days
48+
.\scripts\export-queries.ps1 -ExportPlans -LookbackMinutes 10080
49+
```
50+
51+
### Analyze Execution Plans
52+
53+
After extraction, analyze the .sqlplan files:
54+
55+
**Single plan:**
56+
```powershell
57+
.\SqlAnalyzer.exe --file 'Analysis\input\QueryStoreTopPlans_qid14_pid1_.sqlplan'
58+
```
59+
60+
**All plans:**
61+
```powershell
62+
.\scripts\run-analyzer.ps1
63+
```
64+
65+
## Output Format
66+
67+
Execution plans are saved as:
68+
```
69+
QueryStoreTopPlans_qid<query_id>_pid<plan_id>_<row>.sqlplan
70+
```
71+
72+
Example:
73+
```
74+
QueryStoreTopPlans_qid14_pid1_001.sqlplan
75+
QueryStoreTopPlans_qid28_pid7_004.sqlplan
76+
```
77+
78+
## What Gets Analyzed
79+
80+
The analyzer detects:
81+
- **Expensive Sorts**: Operations without supporting indexes
82+
- **Table Scans**: Full table scans on large tables
83+
- **Index Scans**: Non-selective index usage
84+
- **Missing Indexes**: Optimizer suggestions
85+
- **Implicit Conversions**: Type mismatches preventing index usage
86+
- **High Cost Operators**: Nested loops, hash joins on large sets
87+
- **Key Lookups**: RID/Key lookups indicating missing covering indexes
88+
89+
## Common Use Cases
90+
91+
**Find slow queries:**
92+
```powershell
93+
# Top 10 slowest by duration
94+
.\scripts\export-queries.ps1 -ExportPlans -Top 10 -Metric duration
95+
```
96+
97+
**Find CPU-intensive queries:**
98+
```powershell
99+
# Top 20 by CPU time
100+
.\scripts\export-queries.ps1 -ExportPlans -Top 20 -Metric cpu
101+
```
102+
103+
**Recent performance issues:**
104+
```powershell
105+
# Last hour only
106+
.\scripts\export-queries.ps1 -ExportPlans -LookbackMinutes 60 -Top 10
107+
```
108+
109+
## Next Steps
110+
111+
After analyzing plans:
112+
1. Review JSON reports in Analysis/output or reports/ folder
113+
2. Focus on plans with high-cost operations (>50% cost)
114+
3. Implement missing indexes suggested by optimizer
115+
4. Consider query rewrites for expensive operations
116+
5. Use LLM fixes for eligible violations in the SQL text
117+
118+
## Extract SQL Text Instead
119+
120+
To extract SQL text (not plans):
121+
```powershell
122+
# This is the default - omit -ExportPlans flag
123+
.\scripts\export-queries.ps1 -Top 50 -Metric duration
124+
```
125+
126+
## Reference
127+
128+
- Script: [scripts/export-queries.ps1](file:///c%3A/Projects/Analyzer/scripts/export-queries.ps1)
129+
- Query template: [Queries/QueryStoreTop.sql](file:///c%3A/Projects/Analyzer/Queries/QueryStoreTop.sql)
130+
- Output location: [Analysis/input](file:///c%3A/Projects/Analyzer/Analysis/input)
131+

0 commit comments

Comments
 (0)