@@ -318,7 +318,7 @@ EXEC sys.sp_executesql @nc_sql, @ws_params, @i_out = @nc_out OUTPUT;
318
318
319
319
SELECT @new_columns = CASE @nc_out WHEN 12 THEN 1 ELSE 0 END ;
320
320
321
- SET @msg = N ' New query_store_runtime_stats columns ' + CASE @waitstats
321
+ SET @msg = N ' New query_store_runtime_stats columns ' + CASE @new_columns
322
322
WHEN 0 THEN N ' do not exist, skipping.'
323
323
WHEN 1 THEN N ' exist, will analyze.'
324
324
END ;
@@ -351,6 +351,8 @@ CREATE TABLE #grouped_interval
351
351
total_avg_query_max_used_memory_mb DECIMAL (38 , 2 ) NULL ,
352
352
total_rowcount DECIMAL (38 , 2 ) NULL ,
353
353
total_count_executions BIGINT NULL ,
354
+ total_avg_log_bytes_mb DECIMAL (38 , 2 ) NULL ,
355
+ total_avg_tempdb_space DECIMAL (38 , 2 ) NULL ,
354
356
INDEX gi_ix_dates CLUSTERED (start_range, end_range)
355
357
);
356
358
@@ -970,16 +972,33 @@ SELECT CONVERT(DATE, qsrs.last_execution_time) AS flat_date,
970
972
SUM((qsrs.avg_logical_io_writes* 8 ) / 1024.) / SUM(qsrs.count_executions) AS total_avg_logical_io_writes_mb,
971
973
SUM(( qsrs.avg_query_max_used_memory * 8 ) / 1024.) / SUM(qsrs.count_executions) AS total_avg_query_max_used_memory_mb,
972
974
SUM(qsrs.avg_rowcount) AS total_rowcount,
973
- SUM(qsrs.count_executions) AS total_count_executions
974
- FROM ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_runtime_stats AS qsrs
975
- JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_plan AS qsp
976
- ON qsp.plan_id = qsrs.plan_id
977
- JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_query AS qsq
978
- ON qsq.query_id = qsp.query_id
979
- WHERE 1 = 1
980
- AND qsq.is_internal_query = 0
981
- AND qsp.query_plan IS NOT NULL
982
- ' ;
975
+ SUM(qsrs.count_executions) AS total_count_executions'
976
+ IF @new_columns = 1
977
+ BEGIN
978
+ SET @sql_select + = N' ,
979
+ SUM((qsrs.avg_log_bytes_used) / 1048576.) / SUM(qsrs.count_executions) AS total_avg_log_bytes_mb,
980
+ SUM(avg_tempdb_space_used) / SUM(qsrs.count_executions) AS total_avg_tempdb_space
981
+ '
982
+ END
983
+ IF @new_columns = 0
984
+ BEGIN
985
+ SET @sql_select + = N' ,
986
+ NULL AS total_avg_log_bytes_mb,
987
+ NULL AS total_avg_tempdb_space
988
+ '
989
+ END
990
+
991
+
992
+ SET @sql_select + = N ' FROM ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_runtime_stats AS qsrs
993
+ JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_plan AS qsp
994
+ ON qsp.plan_id = qsrs.plan_id
995
+ JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_query AS qsq
996
+ ON qsq.query_id = qsp.query_id
997
+ WHERE 1 = 1
998
+ AND qsq.is_internal_query = 0
999
+ AND qsp.query_plan IS NOT NULL
1000
+ ' ;
1001
+
983
1002
984
1003
SET @sql_select + = @sql_where;
985
1004
@@ -1000,7 +1019,8 @@ IF @sql_select IS NULL
1000
1019
INSERT #grouped_interval WITH (TABLOCK )
1001
1020
( flat_date, start_range, end_range, total_avg_duration_ms,
1002
1021
total_avg_cpu_time_ms, total_avg_logical_io_reads_mb, total_avg_physical_io_reads_mb,
1003
- total_avg_logical_io_writes_mb, total_avg_query_max_used_memory_mb, total_rowcount, total_count_executions )
1022
+ total_avg_logical_io_writes_mb, total_avg_query_max_used_memory_mb, total_rowcount,
1023
+ total_count_executions, total_avg_log_bytes_mb, total_avg_tempdb_space )
1004
1024
1005
1025
EXEC sys .sp_executesql @stmt = @sql_select,
1006
1026
@params = @sp_params,
@@ -1380,6 +1400,116 @@ EXEC sys.sp_executesql @stmt = @sql_select,
1380
1400
@sp_Top = @Top, @sp_StartDate = @StartDate, @sp_EndDate = @EndDate, @sp_MinimumExecutionCount = @MinimumExecutionCount, @sp_MinDuration = @duration_filter_ms, @sp_StoredProcName = @StoredProcName, @sp_PlanIdFilter = @PlanIdFilter, @sp_QueryIdFilter = @QueryIdFilter;
1381
1401
1382
1402
1403
+ IF @new_columns = 1
1404
+ BEGIN
1405
+
1406
+ RAISERROR (N ' Gathering new 2017 new column info...' , 0 , 1 ) WITH NOWAIT ;
1407
+
1408
+ -- total_avg_log_bytes_mb, total_avg_tempdb_space
1409
+ -- SUM(avg_tempdb_space_used) /
1410
+
1411
+ /* Get highest log byte count plans*/
1412
+
1413
+ RAISERROR (N ' Gathering highest log byte use plans' , 0 , 1 ) WITH NOWAIT ;
1414
+
1415
+ SET @sql_select = N ' SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;' ;
1416
+ SET @sql_select + = N'
1417
+ WITH rowcount_max
1418
+ AS ( SELECT TOP 1
1419
+ gi.start_range,
1420
+ gi.end_range
1421
+ FROM #grouped_interval AS gi
1422
+ ORDER BY gi.total_avg_log_bytes_mb DESC )
1423
+ INSERT #working_plans WITH (TABLOCK)
1424
+ ( plan_id, query_id, pattern )
1425
+ SELECT TOP ( @sp_Top )
1426
+ qsp.plan_id, qsp.query_id, '' log bytes''
1427
+ FROM ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_plan AS qsp
1428
+ JOIN rowcount_max AS dm
1429
+ ON qsp.last_execution_time >= dm.start_range
1430
+ AND qsp.last_execution_time < dm.end_range
1431
+ JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_runtime_stats AS qsrs
1432
+ ON qsrs.plan_id = qsp.plan_id
1433
+ JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_query AS qsq
1434
+ ON qsq.query_id = qsp.query_id
1435
+ JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_query_text AS qsqt
1436
+ ON qsqt.query_text_id = qsq.query_text_id
1437
+ WHERE 1 = 1
1438
+ AND qsq.is_internal_query = 0
1439
+ AND qsp.query_plan IS NOT NULL
1440
+ ' ;
1441
+
1442
+ SET @sql_select + = @sql_where;
1443
+
1444
+ SET @sql_select + = N' ORDER BY qsrs.avg_log_bytes_used DESC
1445
+ OPTION (RECOMPILE);
1446
+ ' ;
1447
+
1448
+ IF @Debug = 1
1449
+ PRINT @sql_select;
1450
+
1451
+ IF @sql_select IS NULL
1452
+ BEGIN
1453
+ RAISERROR (N ' @sql_select is NULL' , 0 , 1 ) WITH NOWAIT ;
1454
+ RETURN ;
1455
+ END ;
1456
+
1457
+ EXEC sys .sp_executesql @stmt = @sql_select,
1458
+ @params = @sp_params,
1459
+ @sp_Top = @Top, @sp_StartDate = @StartDate, @sp_EndDate = @EndDate, @sp_MinimumExecutionCount = @MinimumExecutionCount, @sp_MinDuration = @duration_filter_ms, @sp_StoredProcName = @StoredProcName, @sp_PlanIdFilter = @PlanIdFilter, @sp_QueryIdFilter = @QueryIdFilter;
1460
+
1461
+ /* Get highest row count plans*/
1462
+
1463
+ RAISERROR (N ' Gathering highest row count plans' , 0 , 1 ) WITH NOWAIT ;
1464
+
1465
+ SET @sql_select = N ' SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;' ;
1466
+ SET @sql_select + = N'
1467
+ WITH rowcount_max
1468
+ AS ( SELECT TOP 1
1469
+ gi.start_range,
1470
+ gi.end_range
1471
+ FROM #grouped_interval AS gi
1472
+ ORDER BY gi.total_avg_tempdb_space DESC )
1473
+ INSERT #working_plans WITH (TABLOCK)
1474
+ ( plan_id, query_id, pattern )
1475
+ SELECT TOP ( @sp_Top )
1476
+ qsp.plan_id, qsp.query_id, '' tempdb space''
1477
+ FROM ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_plan AS qsp
1478
+ JOIN rowcount_max AS dm
1479
+ ON qsp.last_execution_time >= dm.start_range
1480
+ AND qsp.last_execution_time < dm.end_range
1481
+ JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_runtime_stats AS qsrs
1482
+ ON qsrs.plan_id = qsp.plan_id
1483
+ JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_query AS qsq
1484
+ ON qsq.query_id = qsp.query_id
1485
+ JOIN ' + QUOTENAME (@DatabaseName) + N' .sys.query_store_query_text AS qsqt
1486
+ ON qsqt.query_text_id = qsq.query_text_id
1487
+ WHERE 1 = 1
1488
+ AND qsq.is_internal_query = 0
1489
+ AND qsp.query_plan IS NOT NULL
1490
+ ' ;
1491
+
1492
+ SET @sql_select + = @sql_where;
1493
+
1494
+ SET @sql_select + = N' ORDER BY qsrs.avg_tempdb_space_used DESC
1495
+ OPTION (RECOMPILE);
1496
+ ' ;
1497
+
1498
+ IF @Debug = 1
1499
+ PRINT @sql_select;
1500
+
1501
+ IF @sql_select IS NULL
1502
+ BEGIN
1503
+ RAISERROR (N ' @sql_select is NULL' , 0 , 1 ) WITH NOWAIT ;
1504
+ RETURN ;
1505
+ END ;
1506
+
1507
+ EXEC sys .sp_executesql @stmt = @sql_select,
1508
+ @params = @sp_params,
1509
+ @sp_Top = @Top, @sp_StartDate = @StartDate, @sp_EndDate = @EndDate, @sp_MinimumExecutionCount = @MinimumExecutionCount, @sp_MinDuration = @duration_filter_ms, @sp_StoredProcName = @StoredProcName, @sp_PlanIdFilter = @PlanIdFilter, @sp_QueryIdFilter = @QueryIdFilter;
1510
+
1511
+ END ;
1512
+
1383
1513
1384
1514
/*
1385
1515
This rolls up the different patterns we find before deduplicating.
@@ -2930,9 +3060,9 @@ UPDATE b
2930
3060
SET b .frequent_execution = CASE WHEN wm .xpm > @execution_threshold THEN 1 END ,
2931
3061
b .near_parallel = CASE WHEN b .query_cost BETWEEN @ctp * (1 - (@ctp_threshold_pct / 100 .0 )) AND @ctp THEN 1 END ,
2932
3062
b .long_running = CASE WHEN wm .avg_duration > @long_running_query_warning_seconds THEN 1
2933
- WHEN wm .max_duration > @long_running_query_warning_seconds THEN 1
2934
- WHEN wm .avg_cpu_time > @long_running_query_warning_seconds THEN 1
2935
- WHEN wm .max_cpu_time > @long_running_query_warning_seconds THEN 1 END ,
3063
+ WHEN wm .max_duration > @long_running_query_warning_seconds THEN 1
3064
+ WHEN wm .avg_cpu_time > @long_running_query_warning_seconds THEN 1
3065
+ WHEN wm .max_cpu_time > @long_running_query_warning_seconds THEN 1 END ,
2936
3066
b .is_key_lookup_expensive = CASE WHEN b .query_cost > (@ctp / 2 ) AND b .key_lookup_cost >= b .query_cost * .5 THEN 1 END ,
2937
3067
b .is_sort_expensive = CASE WHEN b .query_cost > (@ctp / 2 ) AND b .sort_cost >= b .query_cost * .5 THEN 1 END ,
2938
3068
b .is_remote_query_expensive = CASE WHEN b .remote_query_cost >= b .query_cost * .05 THEN 1 END ,
@@ -3153,7 +3283,7 @@ JOIN #working_metrics AS wm
3153
3283
SELECT *
3154
3284
FROM x
3155
3285
WHERE x .rn = 1
3156
- ORDER BY x .query_cost DESC
3286
+ ORDER BY x .last_execution_time
3157
3287
OPTION (RECOMPILE );
3158
3288
3159
3289
END ;
@@ -3165,7 +3295,8 @@ RAISERROR(N'Returning results for failed queries', 0, 1) WITH NOWAIT;
3165
3295
3166
3296
WITH x AS (
3167
3297
SELECT wpt .database_name , ww .query_cost , wm .plan_id , wm .query_id , wpt .query_sql_text , wm .proc_or_function_name , wpt .query_plan_xml , ww .warnings , wpt .pattern ,
3168
- wm .parameter_sniffing_symptoms , wpt .last_force_failure_reason_desc , wpt .top_three_waits , ww .implicit_conversion_info , ww .cached_execution_parameters , wm .count_executions , wm .count_compiles , wm .total_cpu_time , wm .avg_cpu_time ,
3298
+ wm .parameter_sniffing_symptoms , wpt .last_force_failure_reason_desc , wpt .top_three_waits , ww .implicit_conversion_info , ww .cached_execution_parameters ,
3299
+ wm .count_executions , wm .count_compiles , wm .total_cpu_time , wm .avg_cpu_time ,
3169
3300
wm .total_duration , wm .avg_duration , wm .total_logical_io_reads , wm .avg_logical_io_reads ,
3170
3301
wm .total_physical_io_reads , wm .avg_physical_io_reads , wm .total_logical_io_writes , wm .avg_logical_io_writes , wm .total_rowcount , wm .avg_rowcount ,
3171
3302
wm .total_query_max_used_memory , wm .avg_query_max_used_memory , wm .total_tempdb_space_used , wm .avg_tempdb_space_used ,
@@ -3182,7 +3313,7 @@ JOIN #working_metrics AS wm
3182
3313
SELECT *
3183
3314
FROM x
3184
3315
WHERE x .rn = 1
3185
- ORDER BY x .query_cost DESC
3316
+ ORDER BY x .last_execution_time
3186
3317
OPTION (RECOMPILE );
3187
3318
3188
3319
END ;
@@ -3215,7 +3346,7 @@ JOIN #working_metrics AS wm
3215
3346
SELECT *
3216
3347
FROM x
3217
3348
WHERE x .rn = 1
3218
- ORDER BY x .query_cost DESC
3349
+ ORDER BY x .last_execution_time
3219
3350
OPTION (RECOMPILE );
3220
3351
3221
3352
END ;
@@ -3241,7 +3372,7 @@ JOIN #working_metrics AS wm
3241
3372
SELECT *
3242
3373
FROM x
3243
3374
WHERE x .rn = 1
3244
- ORDER BY x .avg_cpu_time DESC
3375
+ ORDER BY x .last_execution_time
3245
3376
OPTION (RECOMPILE );
3246
3377
3247
3378
END ;
@@ -4040,6 +4171,8 @@ BEGIN
4040
4171
gi .total_avg_logical_io_writes_mb ,
4041
4172
gi .total_avg_query_max_used_memory_mb ,
4042
4173
gi .total_rowcount ,
4174
+ gi .total_avg_log_bytes_mb ,
4175
+ gi .total_avg_tempdb_space ,
4043
4176
CONVERT (NVARCHAR (20 ), gi .flat_date ) AS worst_date,
4044
4177
CASE WHEN DATEPART (HOUR, gi .start_range ) = 0 THEN ' midnight '
4045
4178
WHEN DATEPART (HOUR, gi .start_range ) <= 12 THEN CONVERT (NVARCHAR (3 ), DATEPART (HOUR, gi .start_range )) + ' am '
@@ -4085,6 +4218,16 @@ BEGIN
4085
4218
SELECT TOP 1 ' Your worst row count range was on ' + worsts .worst_date + ' between ' + worsts .worst_start_time + ' and ' + worsts .worst_end_time + ' .' AS msg
4086
4219
FROM worsts
4087
4220
ORDER BY worsts .total_rowcount DESC
4221
+ ),
4222
+ logbytes_worst AS (
4223
+ SELECT TOP 1 ' Your worst row count range was on ' + worsts .worst_date + ' between ' + worsts .worst_start_time + ' and ' + worsts .worst_end_time + ' .' AS msg
4224
+ FROM worsts
4225
+ ORDER BY worsts .total_avg_log_bytes_mb DESC
4226
+ ),
4227
+ tempdb_worst AS (
4228
+ SELECT TOP 1 ' Your worst row count range was on ' + worsts .worst_date + ' between ' + worsts .worst_start_time + ' and ' + worsts .worst_end_time + ' .' AS msg
4229
+ FROM worsts
4230
+ ORDER BY worsts .total_avg_tempdb_space DESC
4088
4231
)
4089
4232
INSERT #warning_results ( CheckID, Priority, FindingsGroup, Finding, URL , Details )
4090
4233
SELECT 1002 , 255 , ' Worsts' , ' Worst Duration' , ' N/A' , duration_worst .msg
@@ -4107,6 +4250,12 @@ BEGIN
4107
4250
UNION ALL
4108
4251
SELECT 1002 , 255 , ' Worsts' , ' Worst Row Counts' , ' N/A' , rowcount_worst .msg
4109
4252
FROM rowcount_worst
4253
+ UNION ALL
4254
+ SELECT 1002 , 255 , ' Worsts' , ' Worst Row Counts' , ' N/A' , logbytes_worst .msg
4255
+ FROM logbytes_worst
4256
+ UNION ALL
4257
+ SELECT 1002 , 255 , ' Worsts' , ' Worst Row Counts' , ' N/A' , tempdb_worst .msg
4258
+ FROM tempdb_worst
4110
4259
OPTION (RECOMPILE );
4111
4260
4112
4261
0 commit comments