-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Input sqlserver - Query Stats #7842
Conversation
…sql-server---Lock-Timeouts-with-timeout-greater-than-0
@@ -82,7 +83,7 @@ query_version = 2 | |||
# include_query = [] | |||
|
|||
## A list of queries to explicitly ignore. | |||
exclude_query = [ 'Schedulers' , 'SqlRequests'] | |||
exclude_query = [ 'Schedulers' , 'SqlRequests','QueryStats'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue with adding this to the exclude_query array is that people upgrading probably won't get the change, and so it'll start running by default for them. This is a problem in general with the exclude_query list being updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you upgrade the config file isn't overwritten so if you didn't have it excluded you will get it AFAIK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I'm not too happy about upgrading and getting new queries suddenly. Can we exclude it by default and make you add it to the include_query list instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure I get it, are you proposing to populate both include_queries and exclude_queries of in the default configuration file?
I don't see any cons in that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I'm not sure I understand completely, but it seems like we get two different behaviors for new users to telegraf and upgrading users. New users get the query excluded and upgrading users get the query added. Almost seems like the opposite of what I would expect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure we should be adding everything "new" under include list, that also means every new person that adopts won't get it and have to explicitly include it correct? Certain things like Query level details given more expensive can be excluded by default or relegated to include list only but there has to be a decision on those types of queries. I like a good default queries that are lighter wait, and then include list for the rest if needed which are deemed heavier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are of the same mind there. Do you want to make any changes or are we good to merge?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, now I get it.
Well the query itself can be somehow expensive, like the "sql_requests" one, that's why it has been excluded by default, if you want it, you will have to be explicit about it.
I don't see any solution to this kind of problem though (getting or not new queries on new setups or updates), I hope people read the release notes before upgrading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ssoroka the problem in V2 collector ( what we are trying to address with #7934 ) is t hat all queries are run by default.
@Trovalo if ok we can close this what I propose is the following
a. We do not add this query at all for V2 (given it is heavy duty and is by default going to be run)
b. We do not add this for database_type by default given we don't want this to be run for default
c. A user actually uses include_list if wanted for this. I think Include_list as it stands today has a few issues ( I ran into when using that need to debug).
@Trovalo are you ok either revisiting this after #7934 is merged or doing as part of it as a specific commit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not aware of any issue with include_query, to me we can postpone this after #7934. (to keep things easier)
Solution "c" seems the best one to me, the point is how can we achieve that with given the 2 existing parameters, include and exclude.
For now, let's postpone it, we will see later what and how to do it.
@denzilribeiro can you have a look at this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FOr Azure SQL DB can you also add total_page_server_reads ?
https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-query-stats-transact-sql?view=sql-server-ver15
Also generically query_hash and query_plan_hash are useful ( aka forms of the same query and plan)
I've just added the [total_page_server_reads] column for the Azure version of the query, I haven't tested it yet though. Will it run also on SQL Managed Instance? About [query_hash] and [query_plan_hash], they are already present in the query (both versions) |
Yes total_page_server_reads will run on all versions of Azure SQL Database. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving given small change assuming tested.
@Trovalo You good for me to merge this? |
Yes, for me it's all ok |
@ssoroka, @danielnelson can you merge this PR or is something more needed? |
the actual database name will be fetched by the query. (to check if the same can be applied to azure)
The error is relative to a different plugin, the SQL Server section works properly. |
fixed the truncation of the last char of the "statement_text" string
has conflicts with master |
@Trovalo give me a few days have a though around it there maybe a PR coming for Query store ( which is similiar in nature) and will take deltas of what is different and similar approach could potentially be used here. |
@denzilribeiro, This PR has no activity but I'm still playing around with this query and it already had several iterations in my custom telegraf build. As of now, it looks like this: (it still uses the "old" style) const qmonitorQueryStats string = `
SET DEADLOCK_PRIORITY -10;
DECLARE
@SqlStatement AS nvarchar(max)
,@EngineEdition AS tinyint = CAST(SERVERPROPERTY('EngineEdition') AS int)
,@MajorMinorVersion AS int = CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') as nvarchar),4) AS int)*100 + CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') as nvarchar),3) AS int)
,@Columns AS nvarchar(MAX) = ''
IF @MajorMinorVersion >= 1050 OR @EngineEdition IN (5,8) BEGIN
SET @Columns += N',SUM(qs.[total_rows]) AS [total_rows]'
END
IF (
@MajorMinorVersion >= 1100 AND EXISTS (SELECT * from sys.all_columns WHERE object_id = OBJECT_ID('sys.dm_exec_query_stats') AND [name] = 'total_dop')
) OR @EngineEdition IN (5,8)
BEGIN
SET @Columns += N'
,SUM(qs.[total_dop]) AS [total_dop]
,SUM(qs.[total_grant_kb]) AS [total_grant_kb]
,SUM(qs.[total_used_grant_kb]) AS [total_used_grant_kb]
,SUM(qs.[total_ideal_grant_kb]) AS [total_ideal_grant_kb]
,SUM(qs.[total_reserved_threads]) AS [total_reserved_threads]
,SUM(qs.[total_used_threads]) AS [total_used_threads]'
END
IF (
@MajorMinorVersion = 1300 AND EXISTS (SELECT * from sys.all_columns WHERE object_id = OBJECT_ID('sys.dm_exec_query_stats') AND [name] = 'total_columnstore_segment_reads')
) OR @EngineEdition IN (5,8)
BEGIN
SET @Columns += N'
,SUM(qs.[total_columnstore_segment_reads]) AS [total_columnstore_segment_reads]
,SUM(qs.[total_columnstore_segment_skips]) AS [total_columnstore_segment_skips]'
END
IF @MajorMinorVersion >= 1500 OR @EngineEdition IN (5,8)
BEGIN
SET @Columns += N'
,SUM(qs.[total_spills]) AS [total_spills]'
END
SET @SqlStatement = N'
SELECT TOP(100)
''sqlserver_query_stats'' AS [measurement]
,REPLACE(@@SERVERNAME,''\'','':'') AS [sql_instance]
,pa.[database_name]
,CONVERT(varchar(20),qs.[query_hash],1) as [query_hash]
,CONVERT(varchar(20),qs.[query_plan_hash],1) as [query_plan_hash]
,QUOTENAME(OBJECT_SCHEMA_NAME(qt.objectid,qt.dbid)) + ''.'' + QUOTENAME(OBJECT_NAME(qt.objectid,qt.dbid)) as stmt_object_name
,MIN(SUBSTRING(
qt.[text],
qs.[statement_start_offset] / 2 + 1,
(CASE WHEN qs.[statement_end_offset] = -1
THEN DATALENGTH(qt.[text])
ELSE qs.[statement_end_offset]
END - qs.[statement_start_offset]) / 2 + 1
)) AS statement_text
,DB_NAME(qt.[dbid]) stmt_db_name
,COUNT(DISTINCT qs.[plan_handle]) AS [plan_count]
,SUM(qs.[execution_count]) AS [execution_count]
,SUM(qs.[total_physical_reads]) AS [total_physical_reads]
,SUM(qs.[total_logical_writes]) AS [total_logical_writes]
,SUM(qs.[total_logical_reads]) AS [total_logical_reads]
,SUM(qs.[total_clr_time]/1000) AS [total_clr_time_ms]
,SUM(qs.[total_worker_time]/1000) AS [total_worker_time_ms]
,SUM(qs.[total_elapsed_time]/1000) AS [total_elapsed_time_ms]
' + @Columns + N'
FROM sys.dm_exec_query_stats as qs
OUTER APPLY sys.dm_exec_sql_text(qs.[sql_handle]) AS qt
CROSS APPLY (
SELECT DB_NAME(CONVERT(int, value)) AS [database_name]
FROM sys.dm_exec_plan_attributes(qs.plan_handle)
WHERE attribute = N''dbid''
) AS pa
--WHERE
-- 1 = 1
-- <DatabaseFilter>
GROUP BY
pa.database_name
,qs.query_hash
,qs.query_plan_hash
,qt.objectid
,qt.dbid
ORDER BY
[total_worker_time_ms] DESC
'
EXEC sp_executesql @SqlStatement Here are some points about it and this is the query underneath
Quering Result |
@Trovalo here is the For query store there is a PR in flight.. #8465 Other comment why order by worker time rather than elapsed duration? ORDER BY |
Is this PR still active? Or are we considering #8465 as the latest? |
This is a different one as the PR you mentioned is only about SQL on Azure. I actually have this one up and running on my own, but it's kind of dangerous to put it live as it is, in fact, it would require a minimum time gap between executions, and as of now I have no idea about how to provide this kind of enforcement. If it's spring cleaning time I can just delete this PR, and create a new one once I have some significant breakthrough about how to make it safe. |
Required for all PRs:
closes #7789
This PR adds a new query which gets data from sys.dm_exec_query_stats.
It fetches incremental data about the top 50 queries executed on the SQL Server instance (as long as a query plan is in cache).
The information gathered is at query and exec plan level, useful to check which queries have the longest duration, which often corresponds with the heaviest or most executed queries.
The query has been tested on:
Notes:
My personal opinion is that the information returned by this query ("QueryStats") can complete and/or enrich what is already gathered by "SqlRequests". The difference is that "QueryStats" provides data on a larger timespan, giving a higher-level overview of the situation.
Any feedback is appreciated