@@ -8873,22 +8873,29 @@ BEGIN
88738873 @sql + = N'
88748874 SELECT
88758875 qsq.query_hash,
8876- /* All of these but count_executions are already floats. */
8876+ /* All of these but count_executions are already floats.
8877+ qsrs.avg_* columns are themselves per-interval averages, so
8878+ AVG(avg_*) is an unweighted mean of means. Weight by
8879+ count_executions to get the true cross-interval average —
8880+ otherwise intervals with very few executions get the same
8881+ pull on the number as intervals with many, and regression
8882+ detection skews toward sparse outlier intervals. */
88778883 regression_metric_average =
88788884 CONVERT
88798885 (
88808886 float,
88818887 ' +
88828888 CASE @sort_order
8883- WHEN ' cpu' THEN N ' AVG(qsrs.avg_cpu_time)'
8884- WHEN ' logical reads' THEN N ' AVG(qsrs.avg_logical_io_reads)'
8885- WHEN ' physical reads' THEN N ' AVG(qsrs.avg_physical_io_reads)'
8886- WHEN ' writes' THEN N ' AVG(qsrs.avg_logical_io_writes)'
8887- WHEN ' duration' THEN N ' AVG(qsrs.avg_duration)'
8888- WHEN ' memory' THEN N ' AVG(qsrs.avg_query_max_used_memory)'
8889- WHEN ' tempdb' THEN CASE WHEN @new = 1 THEN N ' AVG(qsrs.avg_tempdb_space_used)' ELSE N ' AVG(qsrs.avg_cpu_time)' END
8889+ WHEN ' cpu' THEN N ' SUM(qsrs.avg_cpu_time * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)'
8890+ WHEN ' logical reads' THEN N ' SUM(qsrs.avg_logical_io_reads * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)'
8891+ WHEN ' physical reads' THEN N ' SUM(qsrs.avg_physical_io_reads * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)'
8892+ WHEN ' writes' THEN N ' SUM(qsrs.avg_logical_io_writes * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)'
8893+ WHEN ' duration' THEN N ' SUM(qsrs.avg_duration * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)'
8894+ WHEN ' memory' THEN N ' SUM(qsrs.avg_query_max_used_memory * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)'
8895+ WHEN ' tempdb' THEN CASE WHEN @new = 1 THEN N ' SUM(qsrs.avg_tempdb_space_used * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)' ELSE N ' SUM(qsrs.avg_cpu_time * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)' END
8896+ /* count_executions per interval is meaningful as a plain mean — it''s a count, not an average-of-averages. */
88908897 WHEN ' executions' THEN N ' AVG(qsrs.count_executions)'
8891- WHEN ' rows' THEN N ' AVG (qsrs.avg_rowcount)'
8898+ WHEN ' rows' THEN N ' SUM (qsrs.avg_rowcount * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )'
88928899 WHEN ' total cpu' THEN N ' SUM(qsrs.avg_cpu_time * qsrs.count_executions)'
88938900 WHEN ' total logical reads' THEN N ' SUM(qsrs.avg_logical_io_reads * qsrs.count_executions)'
88948901 WHEN ' total physical reads' THEN N ' SUM(qsrs.avg_physical_io_reads * qsrs.count_executions)'
@@ -8897,7 +8904,8 @@ BEGIN
88978904 WHEN ' total memory' THEN N ' SUM(qsrs.avg_query_max_used_memory * qsrs.count_executions)'
88988905 WHEN ' total tempdb' THEN CASE WHEN @new = 1 THEN N ' SUM(qsrs.avg_tempdb_space_used * qsrs.count_executions)' ELSE N ' SUM(qsrs.avg_cpu_time * qsrs.count_executions)' END
88998906 WHEN ' total rows' THEN N ' SUM(qsrs.avg_rowcount * qsrs.count_executions)'
8900- ELSE CASE WHEN @sort_order_is_a_wait = 1 THEN N ' AVG(waits.total_query_wait_time_ms)' ELSE N ' AVG(qsrs.avg_cpu_time)' END
8907+ /* Waits and the fallback path — waits are per-interval totals so AVG is correct; fallback mirrors cpu path. */
8908+ ELSE CASE WHEN @sort_order_is_a_wait = 1 THEN N ' AVG(waits.total_query_wait_time_ms)' ELSE N ' SUM(qsrs.avg_cpu_time * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0)' END
89018909 END
89028910 + N'
89038911 )
@@ -8985,22 +8993,25 @@ BEGIN
89858993 @sql + = N'
89868994 SELECT
89878995 qsq.query_hash,
8988- /* All of these but count_executions are already floats. */
8996+ /* All of these but count_executions are already floats.
8997+ Weighted by count_executions so the current-window average
8998+ matches the baseline-window computation (see baseline block
8999+ above) and regression percentages compare like with like. */
89899000 current_metric_average =
89909001 CONVERT
89919002 (
89929003 float,
89939004 ' +
89949005 CASE @sort_order
8995- WHEN ' cpu' THEN N ' AVG (qsrs.avg_cpu_time)'
8996- WHEN ' logical reads' THEN N ' AVG (qsrs.avg_logical_io_reads)'
8997- WHEN ' physical reads' THEN N ' AVG (qsrs.avg_physical_io_reads)'
8998- WHEN ' writes' THEN N ' AVG (qsrs.avg_logical_io_writes)'
8999- WHEN ' duration' THEN N ' AVG (qsrs.avg_duration)'
9000- WHEN ' memory' THEN N ' AVG (qsrs.avg_query_max_used_memory)'
9001- WHEN ' tempdb' THEN CASE WHEN @new = 1 THEN N ' AVG (qsrs.avg_tempdb_space_used) ' ELSE N ' AVG (qsrs.avg_cpu_time)' END
9006+ WHEN ' cpu' THEN N ' SUM (qsrs.avg_cpu_time * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )'
9007+ WHEN ' logical reads' THEN N ' SUM (qsrs.avg_logical_io_reads * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )'
9008+ WHEN ' physical reads' THEN N ' SUM (qsrs.avg_physical_io_reads * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )'
9009+ WHEN ' writes' THEN N ' SUM (qsrs.avg_logical_io_writes * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )'
9010+ WHEN ' duration' THEN N ' SUM (qsrs.avg_duration * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )'
9011+ WHEN ' memory' THEN N ' SUM (qsrs.avg_query_max_used_memory * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )'
9012+ WHEN ' tempdb' THEN CASE WHEN @new = 1 THEN N ' SUM (qsrs.avg_tempdb_space_used * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0) ' ELSE N ' SUM (qsrs.avg_cpu_time * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )' END
90029013 WHEN ' executions' THEN N ' AVG(qsrs.count_executions)'
9003- WHEN ' rows' THEN N ' AVG (qsrs.avg_rowcount)'
9014+ WHEN ' rows' THEN N ' SUM (qsrs.avg_rowcount * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )'
90049015 WHEN ' total cpu' THEN N ' SUM(qsrs.avg_cpu_time * qsrs.count_executions)'
90059016 WHEN ' total logical reads' THEN N ' SUM(qsrs.avg_logical_io_reads * qsrs.count_executions)'
90069017 WHEN ' total physical reads' THEN N ' SUM(qsrs.avg_physical_io_reads * qsrs.count_executions)'
@@ -9009,7 +9020,7 @@ BEGIN
90099020 WHEN ' total memory' THEN N ' SUM(qsrs.avg_query_max_used_memory * qsrs.count_executions)'
90109021 WHEN ' total tempdb' THEN CASE WHEN @new = 1 THEN N ' SUM(qsrs.avg_tempdb_space_used * qsrs.count_executions)' ELSE N ' SUM(qsrs.avg_cpu_time * qsrs.count_executions)' END
90119022 WHEN ' total rows' THEN N ' SUM(qsrs.avg_rowcount * qsrs.count_executions)'
9012- ELSE CASE WHEN @sort_order_is_a_wait = 1 THEN N ' AVG(waits.total_query_wait_time_ms)' ELSE N ' AVG (qsrs.avg_cpu_time)' END
9023+ ELSE CASE WHEN @sort_order_is_a_wait = 1 THEN N ' AVG(waits.total_query_wait_time_ms)' ELSE N ' SUM (qsrs.avg_cpu_time * qsrs.count_executions) / NULLIF(SUM(CONVERT(float, qsrs.count_executions)), 0 )' END
90139024 END
90149025 + N'
90159026 )
0 commit comments