Skip to content

Commit 80cece7

Browse files
Merge pull request #691 from ReeceGoding/try-dm_db_tuning_recommendations
sp_QuickieStore: added sys.dm_db_tuning_recommendations to Expert Mode output
2 parents ab5756f + 84352d2 commit 80cece7

1 file changed

Lines changed: 172 additions & 2 deletions

File tree

sp_QuickieStore/sp_QuickieStore.sql

Lines changed: 172 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,20 @@ CREATE TABLE
13681368
max_query_wait_time_ms bigint NOT NULL
13691369
);
13701370

1371+
/*
1372+
Tuning Recommendations, When Available (2017+)
1373+
*/
1374+
CREATE TABLE
1375+
#tuning_recommendations
1376+
(
1377+
database_id integer NOT NULL,
1378+
score integer NULL,
1379+
last_refresh datetime2 NULL,
1380+
/* These are from JSON, so the true schema cannot be known */
1381+
regressed_plan_id bigint NULL,
1382+
recommended_plan_id bigint NULL
1383+
);
1384+
13711385
/*
13721386
Context is everything
13731387
*/
@@ -1582,6 +1596,7 @@ VALUES
15821596
(90, 'sql_2022', 'plan_type', 'plan_type_desc', 'qsp.plan_type_desc', 1, 'sql_2022_views', 1, 0, NULL),
15831597
/* New version features */
15841598
(95, 'new_features', 'forcing_type', 'plan_forcing_type_desc', 'qsp.plan_forcing_type_desc', 1, 'new', 1, 0, NULL),
1599+
(96, 'new_features', 'forcing_status', 'plan_force_recommendation_status', 'tr.plan_force_recommendation_status', 1, 'new', 1, 1, NULL),
15851600
(97, 'new_features', 'top_waits', 'top_waits', 'w.top_waits', 1, 'new', 1, 0, NULL),
15861601
/* Date/time columns (not conditional, always included) */
15871602
(100, 'execution_time', 'first', 'first_execution_time', 'CASE WHEN @timezone IS NULL THEN SWITCHOFFSET(qsrs.first_execution_time, @utc_offset_string) WHEN @timezone IS NOT NULL THEN qsrs.first_execution_time AT TIME ZONE @timezone END', 0, NULL, NULL, 0, NULL),
@@ -8011,6 +8026,123 @@ OPTION(RECOMPILE);' + @nc10;
80118026
END;
80128027
END; /*End getting wait stats*/
80138028

8029+
/*
8030+
If tuning recommendations are available, we'll grab them here
8031+
*/
8032+
IF
8033+
(
8034+
@new = 1
8035+
AND @expert_mode = 1
8036+
)
8037+
BEGIN
8038+
SELECT
8039+
@current_table = 'inserting #tuning_recommendations',
8040+
@sql = @isolation_level;
8041+
8042+
IF @troubleshoot_performance = 1
8043+
BEGIN
8044+
EXECUTE sys.sp_executesql
8045+
@troubleshoot_insert,
8046+
N'@current_table nvarchar(100)',
8047+
@current_table;
8048+
8049+
SET STATISTICS XML ON;
8050+
END;
8051+
8052+
/* The OPENJSON query doesn't work on pre-2017 compatibility levels. */
8053+
SELECT
8054+
@sql += N'
8055+
SELECT
8056+
@database_id,
8057+
plan_force_flat.score,
8058+
plan_force_flat.last_refresh,
8059+
plan_force_flat.regressed_plan_id,
8060+
plan_force_flat.recommended_plan_id
8061+
FROM
8062+
(
8063+
SELECT
8064+
plan_force_json.score,
8065+
plan_force_json.last_refresh,
8066+
regressed_plan_id =
8067+
SUBSTRING
8068+
(
8069+
plan_force_json.Detail,
8070+
CHARINDEX(''regressedPlanId: '', plan_force_json.detail) + LEN(''regressedPlanId: ''),
8071+
CHARINDEX('','', plan_force_json.detail, CHARINDEX(''regressedPlanId: '', plan_force_json.detail) + LEN('',''))
8072+
- LEN(''regressedPlanId: '') - CHARINDEX(''regressedPlanId: '', plan_force_json.detail)
8073+
),
8074+
recommended_plan_id =
8075+
SUBSTRING
8076+
(
8077+
plan_force_json.detail,
8078+
CHARINDEX(''recommendedPlanId: '', plan_force_json.detail) + LEN(''recommendedPlanId: ''),
8079+
CHARINDEX('','', plan_force_json.detail, CHARINDEX(''recommendedPlanId: '', plan_force_json.detail) + LEN('',''))
8080+
- LEN(''recommendedPlanId: '') - CHARINDEX(''recommendedPlanId: '', plan_force_json.detail)
8081+
)
8082+
FROM
8083+
(
8084+
SELECT
8085+
tr.score,
8086+
tr.last_refresh,
8087+
detail =
8088+
(
8089+
SELECT
8090+
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
8091+
tr.details,
8092+
''{'', ''''), ''}'', ''''), ''"'', ''''), '':'', '': ''), ''planForceDetails: '', ''''), '','', '', '')
8093+
)
8094+
FROM ' + @database_name_quoted + N'.sys.dm_db_tuning_recommendations AS tr
8095+
) AS plan_force_json
8096+
) AS plan_force_flat
8097+
WHERE EXISTS
8098+
(
8099+
SELECT
8100+
1/0
8101+
FROM #query_store_plan AS qsp
8102+
WHERE plan_force_flat.regressed_plan_id = qsp.plan_id
8103+
)
8104+
OPTION(RECOMPILE);' + @nc10;
8105+
8106+
IF @debug = 1
8107+
BEGIN
8108+
PRINT LEN(@sql);
8109+
PRINT @sql;
8110+
END;
8111+
8112+
INSERT
8113+
#tuning_recommendations
8114+
WITH
8115+
(TABLOCK)
8116+
(
8117+
database_id,
8118+
score,
8119+
last_refresh,
8120+
regressed_plan_id,
8121+
recommended_plan_id
8122+
)
8123+
EXECUTE sys.sp_executesql
8124+
@sql,
8125+
N'@database_id integer',
8126+
@database_id;
8127+
8128+
IF @troubleshoot_performance = 1
8129+
BEGIN
8130+
SET STATISTICS XML OFF;
8131+
8132+
EXECUTE sys.sp_executesql
8133+
@troubleshoot_update,
8134+
N'@current_table nvarchar(100)',
8135+
@current_table;
8136+
8137+
EXECUTE sys.sp_executesql
8138+
@troubleshoot_info,
8139+
N'@sql nvarchar(max),
8140+
@current_table nvarchar(100)',
8141+
@sql,
8142+
@current_table;
8143+
END;
8144+
END; /*End getting tuning recommendations*/
8145+
80148146
/*
80158147
This gets context info and settings
80168148
*/
@@ -8927,7 +9059,7 @@ SELECT
89279059
);
89289060

89299061
/*
8930-
Get wait stats if we can
9062+
Get wait stats and tuning recommendations if we can
89319063
*/
89329064
IF
89339065
(
@@ -8996,7 +9128,22 @@ SELECT
89969128
2,
89979129
''''
89989130
)
8999-
) AS w'
9131+
) AS w
9132+
OUTER APPLY
9133+
(
9134+
SELECT TOP (1)
9135+
plan_force_recommendation_status =
9136+
N''Considered regressed from plan_id '' +
9137+
CONVERT(nvarchar(20), qstr.recommended_plan_id) +
9138+
N''. That plan may not be the best plan, but it is scored '' +
9139+
CONVERT(nvarchar(20), qstr.score) +
9140+
N'' out of 100 for being better than this plan.''
9141+
FROM #tuning_recommendations AS qstr
9142+
WHERE qstr.regressed_plan_id = qsrs.plan_id
9143+
AND qstr.database_id = qsrs.database_id
9144+
ORDER BY
9145+
qstr.last_refresh DESC
9146+
) AS tr'
90009147
);
90019148
END; /*End wait stats query*/
90029149

@@ -11601,6 +11748,29 @@ BEGIN
1160111748
END;
1160211749
END;
1160311750

11751+
IF EXISTS
11752+
(
11753+
SELECT
11754+
1/0
11755+
FROM #tuning_recommendations AS qstr
11756+
)
11757+
BEGIN
11758+
SELECT
11759+
table_name =
11760+
'#tuning_recommendations',
11761+
qstr.*
11762+
FROM #tuning_recommendations AS qstr
11763+
ORDER BY
11764+
qstr.regressed_plan_id
11765+
OPTION(RECOMPILE);
11766+
END;
11767+
ELSE
11768+
BEGIN
11769+
SELECT
11770+
result =
11771+
'#tuning_recommendations is empty';
11772+
END;
11773+
1160411774
IF EXISTS
1160511775
(
1160611776
SELECT

0 commit comments

Comments
 (0)