## Kedy použiť Po release, upgrade, zmene indexu alebo compatibility level. ## Ako čítať výsledok `slowdown_factor > 1` = spomalenie. Dôležitý je aj počet vykonaní a absolútny čas – dotaz zo 1 ms na 3 ms je menší problém než z 2 s na 4 s. > [!WARNING] > Potrebuje aspoň 48 hodín dát v Query Store a dostatok vykonaní v **oboch** obdobiach. Intervaly sa na hraniciach prekrývajú, výsledok nie je presný na sekundu. **Oprávnenia:** `VIEW DATABASE STATE` (na SQL Server 2022 stačí aj `VIEW DATABASE PERFORMANCE STATE`). Spúšťa sa v cieľovej databáze. **Režim:** READ ONLY · **Verzia:** SQL Server 2016 – 2022 ## Súvisiace recepty - [Štatistiky – posledný update a počet zmien](script.php?id=29&s=statistiky-posledny-update-a-pocet-zmien) - [Query Store – konfigurácia a stav](script.php?id=46&s=query-store-konfiguracia-a-stav)
Skript
Query Store – regresie (24 h vs. predošlých 24 h)
Dotazy, ktorým za posledných 24 hodín narástlo vážené priemerné trvanie oproti predchádzajúcim 24 hodinám.
Parametre skriptu doplň a kopíruj hotový skript
/* DeadlockCafe | Query Store – regresie (24 h vs. predošlých 24 h)
Účel: Dotazy, ktorým za posledných 24 hodín narástlo vážené priemerné trvanie oproti predchádzajúcim 24 hodinám.
Režim: READ ONLY | SQL Server 2016 – 2022, on-premises
*/
SET NOCOUNT ON;
-- Spusti v cieľovej databáze (Query Store je per databáza)
DECLARE @MinExecutions bigint = {{MinExecutions:10}};
;WITH executions AS
(
SELECT q.query_id, q.query_text_id,
CASE WHEN i.start_time >= DATEADD(HOUR,-24,SYSDATETIMEOFFSET()) THEN 'recent'
WHEN i.start_time >= DATEADD(HOUR,-48,SYSDATETIMEOFFSET()) THEN 'previous'
ELSE 'older' END AS period_name,
rs.count_executions,
CONVERT(float,rs.avg_duration) * rs.count_executions AS weighted_duration_us
FROM sys.query_store_query AS q
JOIN sys.query_store_plan AS p ON p.query_id=q.query_id
JOIN sys.query_store_runtime_stats AS rs ON rs.plan_id=p.plan_id
JOIN sys.query_store_runtime_stats_interval AS i
ON i.runtime_stats_interval_id=rs.runtime_stats_interval_id
WHERE i.start_time >= DATEADD(HOUR,-48,SYSDATETIMEOFFSET())
AND rs.execution_type=0
), pivoted AS
(
SELECT query_id, query_text_id,
SUM(CASE WHEN period_name='previous' THEN count_executions ELSE 0 END) AS previous_count,
SUM(CASE WHEN period_name='recent' THEN count_executions ELSE 0 END) AS recent_count,
SUM(CASE WHEN period_name='previous' THEN weighted_duration_us ELSE 0 END) AS previous_us,
SUM(CASE WHEN period_name='recent' THEN weighted_duration_us ELSE 0 END) AS recent_us
FROM executions
GROUP BY query_id,query_text_id
)
SELECT TOP (30) p.query_id, p.previous_count, p.recent_count,
CAST(p.previous_us/NULLIF(p.previous_count,0)/1000.0 AS decimal(18,2)) AS previous_avg_ms,
CAST(p.recent_us/NULLIF(p.recent_count,0)/1000.0 AS decimal(18,2)) AS recent_avg_ms,
CAST((p.recent_us/NULLIF(p.recent_count,0)) /
NULLIF(p.previous_us/NULLIF(p.previous_count,0),0) AS decimal(18,2)) AS slowdown_factor,
qt.query_sql_text
FROM pivoted AS p
JOIN sys.query_store_query_text AS qt ON qt.query_text_id=p.query_text_id
WHERE p.previous_count >= @MinExecutions AND p.recent_count >= @MinExecutions
ORDER BY (p.recent_us/NULLIF(p.recent_count,0)) /
NULLIF(p.previous_us/NULLIF(p.previous_count,0),0) DESC;