Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit dbbf312

Browse files
Adds same functionality to BQS
YEEHAW
1 parent fd5bd01 commit dbbf312

File tree

1 file changed

+197
-22
lines changed

1 file changed

+197
-22
lines changed

‎sp_BlitzQueryStore.sql‎

Lines changed: 197 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@ OPTION (RECOMPILE);
9595
SELECT @log_size_mb = AVG(((mf.size * 8) / 1024.))
9696
FROM sys.master_files AS mf
9797
WHERE mf.database_id = DB_ID(@DatabaseName)
98-
AND mf.type_desc = 'LOG'
98+
AND mf.type_desc = 'LOG';
9999

100100
/*Grab avg tempdb file size*/
101101
SELECT @avg_tempdb_data_file = AVG(((mf.size * 8) / 1024.))
102102
FROM sys.master_files AS mf
103103
WHERE mf.database_id = DB_ID('tempdb')
104-
AND mf.type_desc = 'ROWS'
104+
AND mf.type_desc = 'ROWS';
105105

106106

107107
/*Help section*/
@@ -173,8 +173,8 @@ IF ( (SELECT SERVERPROPERTY ('EDITION')) = 'SQL Azure' )
173173
SELECT @msg = N'Sorry, sp_BlitzQueryStore doesn''t work on Azure Data Warehouse, or Azure Databases with DB compatibility < 130.' + REPLICATE(CHAR(13), 7933);
174174
PRINT @msg;
175175
RETURN;
176-
END
177-
END
176+
END;
177+
END;
178178
ELSE IF ( (SELECT PARSENAME(CONVERT(NVARCHAR(128), SERVERPROPERTY ('PRODUCTVERSION')), 4) ) < 13 )
179179
BEGIN
180180
SELECT @msg = N'Sorry, sp_BlitzQueryStore doesn''t work on versions of SQL prior to 2016.' + REPLICATE(CHAR(13), 7933);
@@ -200,7 +200,7 @@ IF ( SELECT COUNT(*)
200200
RAISERROR('Checking database validity', 0, 1) WITH NOWAIT;
201201

202202
IF (@is_azure_db = 1)
203-
SET @DatabaseName = DB_NAME()
203+
SET @DatabaseName = DB_NAME();
204204
ELSE
205205
BEGIN
206206

@@ -251,11 +251,11 @@ END;
251251

252252
/*Check database compat level*/
253253

254-
RAISERROR('Checking database compatibility level', 0, 1) WITH NOWAIT
254+
RAISERROR('Checking database compatibility level', 0, 1) WITH NOWAIT;
255255

256256
SELECT @compatibility_level = d.compatibility_level
257257
FROM sys.databases AS d
258-
WHERE d.name = @DatabaseName
258+
WHERE d.name = @DatabaseName;
259259

260260
RAISERROR('The @DatabaseName you specified ([%s])is running in compatibility level ([%d]).', 0, 1, @DatabaseName, @compatibility_level) WITH NOWAIT;
261261

@@ -610,6 +610,8 @@ CREATE TABLE #working_warnings
610610
is_big_log BIT,
611611
is_big_tempdb BIT,
612612
is_paul_white_electric BIT,
613+
implicit_conversion_info XML,
614+
cached_execution_parameters XML,
613615
warnings NVARCHAR(4000)
614616
INDEX ww_ix_ids CLUSTERED (plan_id, query_id, query_hash, sql_handle)
615617
);
@@ -757,7 +759,22 @@ CREATE TABLE #warning_results
757759
FindingsGroup NVARCHAR(50),
758760
Finding NVARCHAR(200),
759761
URL NVARCHAR(200),
760-
Details NVARCHAR(4000)
762+
Details NVARCHAR(4000)
763+
);
764+
765+
DROP TABLE IF EXISTS #stored_proc_info;
766+
767+
CREATE TABLE #stored_proc_info
768+
(
769+
sql_handle VARBINARY(64),
770+
query_hash BINARY(8),
771+
variable_name NVARCHAR(128),
772+
variable_datatype NVARCHAR(128),
773+
compile_time_value NVARCHAR(128),
774+
proc_name NVARCHAR(300),
775+
column_name NVARCHAR(128),
776+
converted_to NVARCHAR(128),
777+
INDEX tf_ix_ids CLUSTERED (sql_handle, query_hash)
761778
);
762779

763780
/*Sets up WHERE clause that gets used quite a bit*/
@@ -878,8 +895,8 @@ IF (@ExportToExcel = 1 OR @SkipXML = 1)
878895
IF @StoredProcName IS NOT NULL
879896
BEGIN
880897

881-
DECLARE @sql NVARCHAR(MAX)
882-
DECLARE @out INT
898+
DECLARE @sql NVARCHAR(MAX);
899+
DECLARE @out INT;
883900
DECLARE @proc_params NVARCHAR(MAX) = N'@sp_StartDate DATETIME2, @sp_EndDate DATETIME2, @sp_MinimumExecutionCount INT, @sp_MinDuration INT, @sp_StoredProcName NVARCHAR(128), @sp_PlanIdFilter INT, @sp_QueryIdFilter INT, @i_out INT OUTPUT';
884901

885902

@@ -904,16 +921,16 @@ IF @StoredProcName IS NOT NULL
904921
BEGIN
905922

906923
SET @msg = N'We couldn''t find the Stored Procedure ' + QUOTENAME(@StoredProcName) + N' in the Query Store views for ' + QUOTENAME(@DatabaseName) + N' between ' + CONVERT(NVARCHAR(30), ISNULL(@StartDate, DATEADD(DAY, -7, DATEDIFF(DAY, 0, SYSDATETIME() ))) ) + N' and ' + CONVERT(NVARCHAR(30), ISNULL(@EndDate, SYSDATETIME())) +
907-
'. Try removing schema prefixes or adjusting dates. If it was executed from a different database context, try searching there instead.'
924+
'. Try removing schema prefixes or adjusting dates. If it was executed from a different database context, try searching there instead.';
908925
RAISERROR(@msg, 0, 1) WITH NOWAIT;
909926

910-
SELECT @msg AS [Blue Flowers, Blue Flowers, Blue Flowers]
927+
SELECT @msg AS [Blue Flowers, Blue Flowers, Blue Flowers];
911928

912929
RETURN;
913930

914-
END
931+
END;
915932

916-
END
933+
END;
917934

918935

919936

@@ -1460,7 +1477,7 @@ SELECT ' + QUOTENAME(@DatabaseName, '''') + N' AS database_name, wp.plan_id, wp.
14601477
((qsrs.last_query_max_used_memory * 8 ) / 1024.),
14611478
((qsrs.min_query_max_used_memory * 8 ) / 1024.),
14621479
((qsrs.max_query_max_used_memory * 8 ) / 1024.),
1463-
qsrs.avg_rowcount, qsrs.last_rowcount, qsrs.min_rowcount, qsrs.max_rowcount,'
1480+
qsrs.avg_rowcount, qsrs.last_rowcount, qsrs.min_rowcount, qsrs.max_rowcount,';
14641481

14651482
IF @new_columns = 1
14661483
BEGIN
@@ -1474,8 +1491,8 @@ SELECT ' + QUOTENAME(@DatabaseName, '''') + N' AS database_name, wp.plan_id, wp.
14741491
((qsrs.last_tempdb_space_used * 8 ) / 1024.),
14751492
((qsrs.min_tempdb_space_used * 8 ) / 1024.),
14761493
((qsrs.max_tempdb_space_used * 8 ) / 1024.)
1477-
'
1478-
END
1494+
';
1495+
END;
14791496
IF @new_columns = 0
14801497
BEGIN
14811498
SET @sql_select += N'
@@ -1491,8 +1508,8 @@ SELECT ' + QUOTENAME(@DatabaseName, '''') + N' AS database_name, wp.plan_id, wp.
14911508
NULL,
14921509
NULL,
14931510
NULL
1494-
'
1495-
END
1511+
';
1512+
END;
14961513
SET @sql_select +=
14971514
N'FROM #working_plans AS wp
14981515
JOIN ' + QUOTENAME(@DatabaseName) + N'.sys.query_store_query AS qsq
@@ -2153,7 +2170,7 @@ SELECT DISTINCT
21532170
c.n.value('(/p:StmtSimple/@StatementEstRows)[1]', 'FLOAT') AS estimated_rows
21542171
FROM #statements AS s
21552172
CROSS APPLY s.statement.nodes('/p:StmtSimple') AS c(n)
2156-
WHERE c.n.exist('/p:StmtSimple[@StatementEstRows > 0]') = 1
2173+
WHERE c.n.exist('/p:StmtSimple[@StatementEstRows > 0]') = 1;
21572174

21582175
UPDATE b
21592176
SET b.estimated_rows = er.estimated_rows
@@ -2652,6 +2669,159 @@ JOIN is_paul_white_electric ipwe
26522669
ON ipwe.sql_handle = b.sql_handle
26532670
OPTION (RECOMPILE);
26542671

2672+
IF EXISTS ( SELECT 1
2673+
FROM #working_warnings AS ww
2674+
WHERE ww.implicit_conversions = 1
2675+
OR ww.proc_or_function_name <> N'Statement')
2676+
BEGIN
2677+
2678+
RAISERROR(N'Getting information about implicit conversions and stored proc parameters', 0, 1) WITH NOWAIT;
2679+
2680+
WITH XMLNAMESPACES ( 'http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p )
2681+
, variables_types
2682+
AS (
2683+
2684+
--WITH XMLNAMESPACES ( 'http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p )
2685+
SELECT
2686+
qp.query_hash,
2687+
qp.sql_handle,
2688+
b.proc_or_function_name AS proc_name,
2689+
q.n.value('@Column', 'NVARCHAR(128)') AS variable_name,
2690+
q.n.value('@ParameterDataType', 'NVARCHAR(128)') AS variable_datatype,
2691+
q.n.value('@ParameterCompiledValue', 'NVARCHAR(1000)') AS compile_time_value
2692+
FROM #query_plan AS qp
2693+
JOIN #working_warnings AS b
2694+
ON b.query_hash = qp.query_hash
2695+
CROSS APPLY qp.query_plan.nodes('//p:QueryPlan/p:ParameterList/p:ColumnReference') AS q(n)
2696+
WHERE b.implicit_conversions = 1 ),
2697+
convert_implicit
2698+
AS (
2699+
--WITH XMLNAMESPACES ( 'http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p )
2700+
SELECT
2701+
qp.query_hash,
2702+
qp.sql_handle,
2703+
b.proc_or_function_name AS proc_name,
2704+
qq.c.value('@Expression', 'NVARCHAR(128)') AS expression,
2705+
SUBSTRING(
2706+
qq.c.value('@Expression', 'NVARCHAR(128)'), --Original Expression
2707+
CHARINDEX('@', qq.c.value('@Expression', 'NVARCHAR(128)')), --Charindex of @+1
2708+
CHARINDEX(']',
2709+
qq.c.value('@Expression', 'NVARCHAR(128)'), --Charindex of end bracket
2710+
CHARINDEX('@', qq.c.value('@Expression', 'NVARCHAR(128)')) + 1 --Starting at the Charindex of the @ +1
2711+
) - CHARINDEX('@', qq.c.value('@Expression', 'NVARCHAR(128)'))) AS variable_name,
2712+
SUBSTRING(
2713+
qq.c.value('@Expression', 'NVARCHAR(128)'), -- Original Expression
2714+
CHARINDEX('].[', qq.c.value('@Expression', 'NVARCHAR(128)')) + 3, --Charindex of ].[ + 3
2715+
CHARINDEX(']',
2716+
qq.c.value('@Expression', 'NVARCHAR(128)'), -- Charindex of end bracket
2717+
CHARINDEX('].[', qq.c.value('@Expression', 'NVARCHAR(128)')) + 3 --Starting at the Charindex of ].[ + 3
2718+
) - CHARINDEX('].[', qq.c.value('@Expression', 'NVARCHAR(128)')) - 3) AS column_name,
2719+
SUBSTRING(
2720+
qq.c.value('@Expression', 'NVARCHAR(128)'), -- Original Expression
2721+
CHARINDEX('(', qq.c.value('@Expression', 'NVARCHAR(128)')) + 1, --Charindex of ( + 1
2722+
CHARINDEX(',',
2723+
qq.c.value('@Expression', 'NVARCHAR(128)'), -- Charindex of comma
2724+
CHARINDEX('(', qq.c.value('@Expression', 'NVARCHAR(128)')) + 1 --Starting at the Charindex of ( + 1
2725+
) - CHARINDEX('(', qq.c.value('@Expression', 'NVARCHAR(128)')) - 1) AS converted_to
2726+
FROM #query_plan AS qp
2727+
JOIN #working_warnings AS b
2728+
ON b.query_hash = qp.query_hash
2729+
CROSS APPLY qp.query_plan.nodes('//p:QueryPlan/p:Warnings/p:PlanAffectingConvert') AS qq(c)
2730+
WHERE qq.c.exist('@ConvertIssue[.="Seek Plan"]') = 1
2731+
AND qp.query_hash IS NOT NULL
2732+
AND b.implicit_conversions = 1 )
2733+
INSERT #stored_proc_info ( query_hash, sql_handle, variable_name, variable_datatype, compile_time_value, proc_name, column_name, converted_to )
2734+
SELECT DISTINCT
2735+
COALESCE(vt.query_hash, ci.query_hash) AS query_hash,
2736+
COALESCE(vt.sql_handle, ci.sql_handle) AS sql_handle,
2737+
COALESCE(vt.variable_name, ci.variable_name) AS variable_name,
2738+
COALESCE(vt.variable_datatype, ci.converted_to) AS variable_datatype,
2739+
COALESCE(vt.compile_time_value, '*declared in proc*') AS compile_time_value,
2740+
COALESCE(vt.proc_name, ci.proc_name) AS proc_name,
2741+
ci.column_name,
2742+
ci.converted_to
2743+
FROM variables_types AS vt
2744+
RIGHT JOIN convert_implicit AS ci
2745+
ON (ci.variable_name = vt.variable_name
2746+
AND ci.query_hash = vt.query_hash)
2747+
OPTION(RECOMPILE);
2748+
2749+
WITH precheck AS (
2750+
SELECT
2751+
spi.sql_handle,
2752+
spi.proc_name,
2753+
CONVERT(XML,
2754+
N'<?ClickMe -- '
2755+
+ @cr + @lf
2756+
+ N'The '
2757+
+ CASE WHEN spi.proc_name <> 'Statement'
2758+
THEN N'stored procedure ' + spi.proc_name
2759+
ELSE N'Statement'
2760+
END
2761+
+ N' had the following implicit conversions: '
2762+
+ CHAR(10)
2763+
+ STUFF((
2764+
SELECT DISTINCT
2765+
@cr + @lf
2766+
+ N'The variable '
2767+
+ spi2.variable_name
2768+
+ N' has a data type of '
2769+
+ spi2.variable_datatype
2770+
+ N' which caused implicit conversion on the column '
2771+
+ spi2.column_name
2772+
+ CASE WHEN spi2.compile_time_value = '*declared in proc*'
2773+
THEN N' and is a declared variable.'
2774+
ELSE N' and is a parameter of the stored procedure.'
2775+
END
2776+
FROM #stored_proc_info AS spi2
2777+
WHERE spi.sql_handle = spi2.sql_handle
2778+
FOR XML PATH(N''), TYPE).value(N'.[1]', N'NVARCHAR(MAX)'), 1, 1, N'')
2779+
+ CHAR(10)
2780+
+ N' -- ?>'
2781+
) AS implicit_conversion_info,
2782+
CONVERT(XML,
2783+
N'<?ClickMe -- '
2784+
+ @cr + @lf
2785+
+ N'EXEC '
2786+
+ spi.proc_name
2787+
+ N' '
2788+
+ STUFF((
2789+
SELECT DISTINCT N', '
2790+
+ spi2.variable_name
2791+
+ N' = '
2792+
+ CASE WHEN spi2.compile_time_value = 'NULL'
2793+
THEN spi2.compile_time_value
2794+
ELSE QUOTENAME(spi2.compile_time_value, '''')
2795+
END
2796+
FROM #stored_proc_info AS spi2
2797+
WHERE spi.sql_handle = spi2.sql_handle
2798+
AND spi2.proc_name <> 'Statement'
2799+
AND spi2.compile_time_value <> '*declared in proc*'
2800+
FOR XML PATH(N''), TYPE).value(N'.[1]', N'NVARCHAR(MAX)'), 1, 1, N'')
2801+
+ @cr + @lf
2802+
+ N' -- ?>'
2803+
) AS cached_execution_parameters
2804+
FROM #stored_proc_info AS spi
2805+
GROUP BY spi.sql_handle, spi.proc_name
2806+
)
2807+
UPDATE b
2808+
SET b.implicit_conversion_info = pk.implicit_conversion_info,
2809+
b.cached_execution_parameters = pk.cached_execution_parameters
2810+
FROM #working_warnings AS b
2811+
JOIN precheck pk
2812+
ON pk.sql_handle = b.sql_handle
2813+
AND b.implicit_conversions = 1
2814+
OPTION(RECOMPILE);
2815+
2816+
END; --End implicit conversion information gathering
2817+
2818+
UPDATE b
2819+
SET b.implicit_conversion_info = CASE WHEN b.implicit_conversion_info IS NULL THEN '<?NoNeedToClickMe -- N/A --?>' ELSE b.implicit_conversion_info END,
2820+
b.cached_execution_parameters = CASE WHEN b.cached_execution_parameters IS NULL THEN '<?NoNeedToClickMe -- N/A --?>' ELSE b.cached_execution_parameters END
2821+
FROM #working_warnings AS b
2822+
OPTION(RECOMPILE);
2823+
2824+
26552825
RAISERROR(N'General query dispositions: frequent executions, long running, etc.', 0, 1) WITH NOWAIT;
26562826

26572827
WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p)
@@ -2862,9 +3032,10 @@ BEGIN
28623032

28633033
RAISERROR(N'Returning regular results', 0, 1) WITH NOWAIT;
28643034

3035+
28653036
WITH x AS (
28663037
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,
2867-
wm.parameter_sniffing_symptoms, wpt.top_three_waits, wm.count_executions, wm.count_compiles, wm.total_cpu_time, wm.avg_cpu_time,
3038+
wm.parameter_sniffing_symptoms, 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,
28683039
wm.total_duration, wm.avg_duration, wm.total_logical_io_reads, wm.avg_logical_io_reads,
28693040
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,
28703041
wm.total_query_max_used_memory, wm.avg_query_max_used_memory, wm.total_tempdb_space_used, wm.avg_tempdb_space_used,
@@ -2893,7 +3064,7 @@ RAISERROR(N'Returning results for failed queries', 0, 1) WITH NOWAIT;
28933064

28943065
WITH x AS (
28953066
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,
2896-
wm.parameter_sniffing_symptoms, wpt.last_force_failure_reason_desc, wpt.top_three_waits, wm.count_executions, wm.count_compiles, wm.total_cpu_time, wm.avg_cpu_time,
3067+
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,
28973068
wm.total_duration, wm.avg_duration, wm.total_logical_io_reads, wm.avg_logical_io_reads,
28983069
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,
28993070
wm.total_query_max_used_memory, wm.avg_query_max_used_memory, wm.total_tempdb_space_used, wm.avg_tempdb_space_used,
@@ -3955,6 +4126,10 @@ SELECT '#est_rows' AS table_name, *
39554126
FROM #est_rows AS er
39564127
OPTION (RECOMPILE);
39574128

4129+
SELECT '#stored_proc_info' AS table_name, *
4130+
FROM #stored_proc_info AS spi
4131+
OPTION(RECOMPILE);
4132+
39584133
END;
39594134

39604135
END TRY

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /