Skip to content

Commit 93dc088

Browse files
authored
Merge pull request #3834 from BrentOzarULTD/3670_documentation
#3670 Add AI documentation page (Using_AI.md)
2 parents bc6a8e6 + 7237905 commit 93dc088

2 files changed

Lines changed: 344 additions & 1 deletion

File tree

Documentation/Using_AI.md

Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
# Using AI with the First Responder Kit
2+
3+
sp_BlitzCache and sp_BlitzIndex can build AI prompts with your query and index data, and optionally call an AI provider (OpenAI or Google Gemini) to return recommendations directly in the result set.
4+
5+
- **`@AI = 2`** - Builds the AI prompt and returns it in the result set so you can copy/paste it into ChatGPT, Gemini, or another AI tool. Works on all supported versions of SQL Server and Azure SQL DB, no setup required.
6+
- **`@AI = 1`** - Does everything `@AI = 2` does, plus calls the AI API directly from SQL Server and returns advice in the result set. Requires SQL Server 2025 or Azure SQL DB (uses `sp_invoke_external_rest_endpoint`).
7+
8+
## Getting Started: Generate Prompts with @AI = 2
9+
10+
The fastest way to try the AI features is `@AI = 2`. No credentials, no config tables, no API keys - just run the proc and copy the prompt into your favorite AI tool. (We named this AI = 2 because in the really long term - like a decade from now - we expect everybody to be on SQL Server 2025 or Azure SQL DB, and they'll just use AI = 1.)
11+
12+
### sp_BlitzCache: Get Query Tuning Prompts
13+
14+
```sql
15+
EXEC sp_BlitzCache @Top = 1, @AI = 2;
16+
```
17+
18+
The result set includes an **AI Prompt** column containing a pre-built prompt with the query text, execution plan, and performance metrics. Copy and paste it into ChatGPT, Gemini, Claude, or any AI tool.
19+
20+
### sp_BlitzIndex: Get Index Advice Prompts
21+
22+
sp_BlitzIndex's AI feature works in single-table mode (when `@TableName` is specified):
23+
24+
```sql
25+
EXEC sp_BlitzIndex
26+
@DatabaseName = 'YourDatabase',
27+
@SchemaName = 'dbo',
28+
@TableName = 'YourTable',
29+
@AI = 2;
30+
```
31+
32+
The **AI Prompt** column contains a prompt with four data sections about your table, the same kinds of
33+
34+
1. **Existing Indexes** - Index names, types, key columns, include columns, filters, uniqueness, primary key status, and usage statistics (seeks, scans, lookups, writes, row counts).
35+
2. **Missing Index Suggestions** - SQL Server's missing index DMV data including equality/inequality/include columns, benefit numbers, and suggested CREATE INDEX statements.
36+
3. **Column Data Types** - All columns in the table with their data types, nullability, and identity status.
37+
4. **Foreign Keys** - Foreign key names, parent/referenced columns, and whether they are disabled or not trusted.
38+
39+
The AI result sets appear immediately after the missing index result set in sp_BlitzIndex's output.
40+
41+
### Building Your Own Custom Prompts
42+
43+
If you want to override the default prompts, create a table to store your prompt variations. Here's the structure we use, and a few sample ideas for sp_BlitzCache prompts:
44+
45+
```sql
46+
CREATE TABLE dbo.Blitz_AI_Prompts
47+
(Id INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
48+
PromptNickname NVARCHAR(200),
49+
AI_System_Prompt NVARCHAR(4000),
50+
Payload_Template NVARCHAR(4000),
51+
DefaultPrompt BIT DEFAULT 0);
52+
53+
INSERT INTO dbo.Blitz_AI_Prompts (PromptNickname, DefaultPrompt, AI_System_Prompt)
54+
VALUES ('sp_BlitzCache Default', 0, 'You are a very senior database developer working with Microsoft SQL Server and Azure SQL DB. You focus on real-world, actionable advice that will make a big difference, quickly. You value everyone''s time, and while you are friendly and courteous, you do not waste time with pleasantries or emoji because you work in a fast-paced corporate environment.
55+
56+
You have a query that isn''t performing to end user expectations. You have been tasked with making serious improvements to it, quickly. You are not allowed to change server-level settings or make frivolous suggestions like updating statistics. Instead, you need to focus on query changes or index changes.
57+
58+
Do not offer followup options: the customer can only contact you once, so include all necessary information, tasks, and scripts in your initial reply. Render your output in Markdown, as it will be shown in plain text to the customer.');
59+
60+
INSERT INTO dbo.Blitz_AI_Prompts (PromptNickname, DefaultPrompt, AI_System_Prompt)
61+
VALUES ('sp_BlitzCache Index Tuning', 0, 'You are a very senior database developer working with Microsoft SQL Server and Azure SQL DB. You focus on real-world, actionable advice that will make a big difference, quickly. You value everyone''s time, and while you are friendly and courteous, you do not waste time with pleasantries or emoji because you work in a fast-paced corporate environment.
62+
63+
You have a query that isn''t performing to end user expectations. You have been tasked with making serious improvements to it, quickly, but you are only allowed to make index changes. You are not allowed to make changes to the query, server-level settings, database settings, etc.
64+
65+
Do not offer followup options: the customer can only contact you once, so include all necessary information, tasks, and scripts in your initial reply. Render your output in Markdown, as it will be shown in plain text to the customer.');
66+
67+
INSERT INTO dbo.Blitz_AI_Prompts (PromptNickname, DefaultPrompt, AI_System_Prompt)
68+
VALUES ('sp_BlitzCache Deadlock Tuning', 0, 'You are a very senior database developer working with Microsoft SQL Server and Azure SQL DB. You focus on real-world, actionable advice that will make a big difference, quickly. You value everyone''s time, and while you are friendly and courteous, you do not waste time with pleasantries or emoji because you work in a fast-paced corporate environment.
69+
70+
You have a query that is experiencing deadlocks and blocking. You have been tasked with making serious improvements to it, quickly. You are not allowed to change server-level or database-level settings nor make frivolous suggestions like updating statistics. Instead, you need to focus on query changes or index changes that will reduce blocking and deadlocks.
71+
72+
Do not offer followup options: the customer can only contact you once, so include all necessary information, tasks, and scripts in your initial reply. Render your output in Markdown, as it will be shown in plain text to the customer.');
73+
74+
INSERT INTO dbo.Blitz_AI_Prompts (PromptNickname, DefaultPrompt, AI_System_Prompt)
75+
VALUES ('sp_BlitzCache Modernize', 0, 'You are a very senior database developer working with Microsoft SQL Server and Azure SQL DB. You focus on real-world, actionable advice that will make a big difference, quickly. You value everyone''s time, and while you are friendly and courteous, you do not waste time with pleasantries or emoji because you work in a fast-paced corporate environment.
76+
77+
You have been given a legacy query that needs to be modernized. Our goals are to make the query run faster, make it easier to understand, easier to maintain, and to take advantage of new features up to and including SQL Server 2025. You have been tasked with making serious improvements to it, quickly, without touching server-level settings, database-level settings, indexes, or statistics.
78+
79+
Do not offer followup options: the customer can only contact you once, so include all necessary information, tasks, and scripts in your initial reply. Render your output in Markdown, as it will be shown in plain text to the customer.');
80+
```
81+
82+
When you want to use one of those custom prompts, call sp_BlitzCache or sp_BlitzIndex like this:
83+
84+
```sql
85+
EXEC sp_BlitzCache @Top = 1, @AI = 2,
86+
@AIPromptConfigTable = 'master.dbo.Blitz_AI_Prompts',
87+
@AIPrompt = 'sp_BlitzCache Modernize';
88+
```
89+
90+
### Using a Database Constitution for Company Standards
91+
92+
Microsoft has implemented [database instructions](https://learn.microsoft.com/en-us/ssms/github-copilot/database-instructions) to influence the advice of GitHub Copilot and SSMS Copilot, and we support that in the First Responder Kit too.
93+
94+
Both sp_BlitzCache and sp_BlitzIndex support a database-level "constitution" - an extended property that provides additional context to the AI about your database's specific rules and constraints. Here's an example constitution:
95+
96+
```sql
97+
EXECUTE sp_addextendedproperty
98+
@name = N'CONSTITUTION.md',
99+
@value = N'Any objects and T-SQL in this database must comply with the organizational standards and guidelines outlined in this constitution document.
100+
101+
## Object Naming Standards
102+
103+
Views must always be prefixed with vw_.
104+
Tables should never be prefixed with tbl_.
105+
Table and column names should be in PascalCase with a capitalized first letter, like UserProperties or SalesByMonth.
106+
Index names should be based on the key columns in the index. If the index has include columns, add an _inc suffix to the index name.
107+
Index names should never be prefixed with table names, idx_, ix_, or any variation thereof.
108+
109+
## Query Standards
110+
111+
Queries should be written in a concise, easy-to-understand, performant way.
112+
Queries should prefer CTEs over temp tables unless that presents a performance issue for the query.';
113+
```
114+
115+
When present, the constitution text is included with the AI prompt, giving the AI additional context about your environment.
116+
117+
You can also set up instructions at the object level (example below), but as of this writing, we don't include that with the AI prompt yet. Only one agents property per object is allowed, so you'll want to consolidate all of your information about that object in one property.
118+
119+
```sql
120+
EXECUTE sp_addextendedproperty
121+
@name = N'AGENTS.md',
122+
@value = N'The Views column represents the number of times other people have viewed this user profile.
123+
The AboutMe column is an NVARCHAR(MAX), but only 4000 characters of content should be allowed for inserts and updates.',
124+
@level0type = N'SCHEMA',
125+
@level0name = N'dbo',
126+
@level1type = N'TABLE',
127+
@level1name = N'Users';
128+
```
129+
130+
131+
## Setting Up for @AI = 1: Direct API Calls
132+
133+
To have SQL Server call the AI API directly, you need database-scoped credentials and (optionally) configuration tables.
134+
135+
### Enable External REST Endpoints (SQL Server 2025 only)
136+
137+
```sql
138+
/* Not needed on Azure SQL DB */
139+
EXEC sp_configure 'external rest endpoint enabled', 1;
140+
RECONFIGURE WITH OVERRIDE;
141+
```
142+
143+
### Create a Master Key
144+
145+
Each database that stores credentials needs a master key:
146+
147+
```sql
148+
USE YourDatabase;
149+
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword!';
150+
```
151+
152+
### Create Credentials for OpenAI (ChatGPT)
153+
154+
```sql
155+
CREATE DATABASE SCOPED CREDENTIAL [https://api.openai.com/]
156+
WITH IDENTITY = 'HTTPEndpointHeaders',
157+
SECRET = '{"Authorization":"Bearer YOUR_OPENAI_API_KEY_HERE"}';
158+
```
159+
160+
### Create Credentials for Google Gemini
161+
162+
```sql
163+
CREATE DATABASE SCOPED CREDENTIAL [https://generativelanguage.googleapis.com/]
164+
WITH IDENTITY = 'HTTPEndpointHeaders',
165+
SECRET = N'{"x-goog-api-key":"YOUR_GEMINI_API_KEY_HERE"}';
166+
```
167+
168+
### Grant Access to the Credential
169+
170+
Create a role so you can control who can use the AI features:
171+
172+
```sql
173+
CREATE ROLE [DBA_AI];
174+
GRANT REFERENCES ON DATABASE SCOPED CREDENTIAL::[https://api.openai.com/] TO [DBA_AI];
175+
/* Or for Gemini: */
176+
GRANT REFERENCES ON DATABASE SCOPED CREDENTIAL::[https://generativelanguage.googleapis.com/] TO [DBA_AI];
177+
```
178+
179+
### Configuration Tables (Optional)
180+
181+
You can create configuration tables to store AI provider settings and prompt templates. This avoids passing parameters every time and lets you switch between providers easily. If you don't create these tables, the procs use built-in defaults (OpenAI gpt-5-nano).
182+
183+
#### AI Providers Table
184+
185+
```sql
186+
CREATE TABLE dbo.Blitz_AI_Providers
187+
(Id INT PRIMARY KEY CLUSTERED,
188+
AI_Model NVARCHAR(100),
189+
AI_URL NVARCHAR(500),
190+
AI_Database_Scoped_Credential_Name NVARCHAR(500),
191+
AI_Parameters NVARCHAR(4000),
192+
Timeout_Seconds TINYINT,
193+
Context INT,
194+
DefaultModel BIT DEFAULT 0);
195+
196+
/* OpenAI example: */
197+
INSERT INTO dbo.Blitz_AI_Providers (Id, AI_Model, AI_URL, AI_Database_Scoped_Credential_Name, Timeout_Seconds, DefaultModel)
198+
VALUES (1, N'gpt-5-nano', N'https://api.openai.com/v1/chat/completions',
199+
N'https://api.openai.com/', 230, 1);
200+
201+
/* Gemini example: */
202+
INSERT INTO dbo.Blitz_AI_Providers (Id, AI_Model, AI_URL, AI_Database_Scoped_Credential_Name, Timeout_Seconds, DefaultModel)
203+
VALUES (2, N'gemini-2.5-flash', N'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent',
204+
N'https://generativelanguage.googleapis.com/', 230, 0);
205+
```
206+
207+
208+
## sp_BlitzCache with @AI = 1
209+
210+
Once credentials are set up, sp_BlitzCache can call the AI API directly and return advice in the result set.
211+
212+
### Quick Start with OpenAI
213+
214+
```sql
215+
EXEC sp_BlitzCache @Top = 1, @AI = 1;
216+
```
217+
218+
That's it - the defaults use OpenAI's `gpt-5-nano` model. The result set includes the AI's query tuning recommendations.
219+
220+
### Using Google Gemini
221+
222+
Gemini requires specifying the model and URL:
223+
224+
```sql
225+
EXEC sp_BlitzCache @Top = 1, @AI = 1,
226+
@AIModel = N'gemini-2.5-flash',
227+
@AIURL = N'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent';
228+
```
229+
230+
### Using Configuration Tables
231+
232+
```sql
233+
/* Use the default model from your config table */
234+
EXEC sp_BlitzCache @Top = 1, @AI = 1,
235+
@AIConfigTable = 'master.dbo.Blitz_AI_Providers';
236+
237+
/* Use a specific model from your config table */
238+
EXEC sp_BlitzCache @Top = 1, @AI = 1,
239+
@AIConfigTable = 'master.dbo.Blitz_AI_Providers',
240+
@AIModel = 'gemini-2.5-flash';
241+
242+
/* Use a custom prompt from your prompts table */
243+
EXEC sp_BlitzCache @Top = 1, @AI = 1,
244+
@AIConfigTable = 'master.dbo.Blitz_AI_Providers',
245+
@AIPromptConfigTable = 'master.dbo.Blitz_AI_Prompts',
246+
@AIPrompt = 'index_focused';
247+
```
248+
249+
### sp_BlitzCache AI Parameters
250+
251+
| Parameter | Default | Description |
252+
|-----------|---------|-------------|
253+
| `@AI` | 0 | 0 = off, 1 = call AI API, 2 = generate prompt only |
254+
| `@AIModel` | `gpt-5-nano` | Model name. If it starts with `gemini`, the Gemini URL and payload template are used automatically. |
255+
| `@AIURL` | `https://api.openai.com/v1/chat/completions` | API endpoint URL. Auto-detected for Gemini models. |
256+
| `@AICredential` | Auto-detected from URL | Database-scoped credential name. Defaults to the root of your `@AIURL` with trailing slash. |
257+
| `@AIConfigTable` | NULL | Three-part name of your providers config table (e.g., `master.dbo.Blitz_AI_Providers`). |
258+
| `@AIPromptConfigTable` | NULL | Three-part name of your prompts config table. |
259+
| `@AIPrompt` | NULL | Which prompt nickname to use from the prompts table. |
260+
261+
### sp_BlitzCache AI Result Sets
262+
263+
With `@AI = 1`, the result set includes:
264+
265+
- **AI Advice** - The AI's recommendations as XML text
266+
- **AI Prompt** - The full prompt that was sent (system prompt + query data)
267+
- **AI Payload** - The raw JSON payload sent to the API
268+
- **AI Raw Response** - The full API response JSON (useful for debugging)
269+
270+
With `@AI = 2`, only the **AI Prompt** column is included in the result set.
271+
272+
## sp_BlitzIndex with @AI = 1
273+
274+
Once credentials are set up, sp_BlitzIndex can call the AI API directly and return index recommendations. This only works in single-table mode (when `@TableName` is specified).
275+
276+
### Quick Start with OpenAI
277+
278+
```sql
279+
EXEC sp_BlitzIndex
280+
@DatabaseName = 'YourDatabase',
281+
@SchemaName = 'dbo',
282+
@TableName = 'YourTable',
283+
@AI = 1;
284+
```
285+
286+
### Using Google Gemini
287+
288+
```sql
289+
EXEC sp_BlitzIndex
290+
@DatabaseName = 'YourDatabase',
291+
@SchemaName = 'dbo',
292+
@TableName = 'YourTable',
293+
@AI = 1,
294+
@AIModel = N'gemini-2.5-flash',
295+
@AIURL = N'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent';
296+
```
297+
298+
### Using Configuration Tables
299+
300+
```sql
301+
EXEC sp_BlitzIndex
302+
@DatabaseName = 'YourDatabase',
303+
@SchemaName = 'dbo',
304+
@TableName = 'YourTable',
305+
@AI = 1,
306+
@AIConfigTable = 'master.dbo.Blitz_AI_Providers';
307+
```
308+
309+
### sp_BlitzIndex AI Parameters
310+
311+
| Parameter | Default | Description |
312+
|-----------|---------|-------------|
313+
| `@AI` | 0 | 0 = off, 1 = call AI API, 2 = generate prompt only |
314+
| `@AIModel` | `gpt-5-nano` | Model name. Gemini models auto-detect URL and payload template. |
315+
| `@AIURL` | `https://api.openai.com/v1/chat/completions` | API endpoint URL. |
316+
| `@AICredential` | Auto-detected from URL | Database-scoped credential name. |
317+
| `@AIConfigTable` | NULL | Three-part name of your providers config table. |
318+
| `@AIPromptConfigTable` | NULL | Three-part name of your prompts config table. |
319+
| `@AIPrompt` | NULL | Which prompt nickname to use from the prompts table. |
320+
321+
### sp_BlitzIndex AI Result Sets
322+
323+
The AI result sets appear immediately after the missing index result set.
324+
325+
With `@AI = 1`:
326+
327+
- **AI Advice** - The AI's index recommendations as XML text
328+
- **AI Prompt** - The full prompt sent to the AI (system prompt + all four data sections)
329+
- **AI Payload** - The raw JSON payload sent to the API
330+
- **AI Raw Response** - The full API response JSON
331+
332+
With `@AI = 2`:
333+
334+
- **AI Prompt** - The full prompt, ready to copy/paste into your AI tool of choice
335+
336+
## Tips
337+
338+
- **Start with `@AI = 2`** to review the prompt before spending API credits. You can paste it into any AI tool to verify the output quality.
339+
- **Database context matters** for `@AI = 1`: you must run the query in the database where your credentials are stored, or the API call will fail.
340+
- **Timeout**: The default timeout is 230 seconds. Larger models may need the full timeout; smaller models like `gpt-5-nano` respond in seconds.
341+
- **Cost**: Each call sends your query/index data to the AI provider and costs API credits. Use `@Top = 1` with sp_BlitzCache to limit costs during testing.
342+
- **Security**: Your query text, index definitions, and table structures are sent to the AI provider's API. Do not use this feature if your data or schema is subject to restrictions on external sharing.

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ Other common parameters include:
189189

190190
In addition to the [parameters common to many of the stored procedures](#parameters-common-to-many-of-the-stored-procedures), here are the ones specific to sp_BlitzCache:
191191

192-
* @AskAI - when set to 2, returns a prompt you can copy into your favorite LLM to get advice on the query. When set to 1, we'll actually call the LLM for you on SQL Server 2025 or newer, or Azure SQL DB. [Instructions on setting that up.](https://www.brentozar.com/archive/2025/12/get-chatgpts-advice-on-your-queries-with-sp_blitzcache/)
192+
* @AskAI - when set to 2, returns a prompt you can copy into your favorite LLM to get advice on the query. When set to 1, we'll actually call the LLM for you on SQL Server 2025 or newer, or Azure SQL DB. [Learn more about using AI with the First Responder Kit.](Documentation/Using_AI.md)
193193
* @OnlyQueryHashes - if you want to examine specific query plans, you can pass in a comma-separated list of them in a string.
194194
* @IgnoreQueryHashes - if you know some queries suck and you don't want to see them, you can pass in a comma-separated list of them.
195195
* @OnlySqlHandles, @IgnoreSqlHandles - just like the above two params
@@ -287,6 +287,7 @@ sp_BlitzIndex focuses on mainstream index types. Other index types have varying
287287

288288
In addition to the [parameters common to many of the stored procedures](#parameters-common-to-many-of-the-stored-procedures), here are the ones specific to sp_BlitzIndex:
289289

290+
* @AskAI - when set to 2, returns a prompt you can copy into your favorite LLM to get index advice for a table (requires @TableName). When set to 1, we'll actually call the LLM for you on SQL Server 2025 or newer, or Azure SQL DB. [Learn more about using AI with the First Responder Kit.](Documentation/Using_AI.md)
290291
* @SkipPartitions = 1 - add this if you want to analyze large partitioned tables. We skip these by default for performance reasons.
291292
* @SkipStatistics = 0 - right now, by default, we skip statistics analysis because we've had some performance issues on this.
292293
* @UsualStatisticsSamplingPercent = 100 (default) - By default, @SkipStatistics = 0 with either @Mode = 0 or @Mode = 4 does not inform you of persisted statistics sample rates if that rate is 100. Use a different float if you usually persist a different sample percentage and do not want to be warned about it. Use NULL if you want to hear about every persisted sample rate.

0 commit comments

Comments
 (0)