在 SQL Server 2016 生产机器上使用 Brent Ozar 的免费 SQL 运行状况检查脚本时,我需要多小心,这台机器已经很满了,而且已经很忙了?是否有人在运行以下任何一项时遇到内存、CPU 或 I/O 问题?感谢您的任何反馈。
- sp_Blitz
- sp_BlitzCache
- sp_BlitzFirst
- sp_BlitzIndex
- sp_BlitzLock
- sp_BlitzQueryStore
- sp_BlitzWho
- sp_WhoIsActive (Adam Machanic)
我不会没有它。我们有 Redgate,我更经常使用 Brents 工具。
我们的数据库是 3 Tb,大约有。每秒 1500 次查询,从未遇到任何问题。
制作了一个依赖于 sp_BlitzWho 的自定义 sp_BlitzWho_Ext。
它采用 sp_BlitzWho 的结果。把它放在一个临时表中,这样我就可以添加一个过滤器。游标也被识别和转换,因此您可以看到实际的查询。
删除它们每个的 plan_cache 的 SQL 都在那里 - 所以每当我们得到一个愚蠢的计划时,很容易找到并删除正确的计划。
现在只需 5 秒即可确定罪魁祸首并放弃计划。
首先,我创建了一个函数来从光标中获取查询文本
create function [dbo].[CursorQuery]
(
@session_id int
) returns nvarchar(255)
as
begin
declare @ret nvarchar(255) = null
SELECT @ret = t.text
FROM sys.dm_exec_cursors (@session_id) c
LEFT JOIN sys.dm_exec_sessions AS es ON c.session_id = es.session_id
CROSS APPLY sys.dm_exec_sql_text (c.sql_handle) t
return @ret
end
然后是存储过程
CREATE PROCEDURE [dbo].[sp_BlitzWho_Ext]
AS
BEGIN
CREATE TABLE #BlitzWhoResult
(
[run_date] VARCHAR(255),
[elapsed_time] [varchar](41) NULL,
[session_id] [smallint] NOT NULL,
[database_name] [nvarchar](128) NULL,
[query_text] [nvarchar](max) NULL,
[query_plan] [xml] NULL,
[live_query_plan] [xml] NULL,
[query_cost] [float] NULL,
[status] [nvarchar](30) NOT NULL,
[wait_info] [nvarchar](max) NULL,
[top_session_waits] [nvarchar](max) NULL,
[blocking_session_id] [smallint] NULL,
[open_transaction_count] [int] NULL,
[is_implicit_transaction] [int] NOT NULL,
[nt_domain] [nvarchar](128) NULL,
[host_name] [nvarchar](128) NULL,
[login_name] [nvarchar](128) NOT NULL,
[nt_user_name] [nvarchar](128) NULL,
[program_name] [nvarchar](128) NULL,
[fix_parameter_sniffing] [nvarchar](150) NULL,
[client_interface_name] [nvarchar](32) NULL,
[login_time] [datetime] NOT NULL,
[start_time] [datetime] NULL,
[request_time] [datetime] NULL,
[request_cpu_time] [int] NULL,
[request_logical_reads] [bigint] NULL,
[request_writes] [bigint] NULL,
[request_physical_reads] [bigint] NULL,
[session_cpu] [int] NOT NULL,
[session_logical_reads] [bigint] NOT NULL,
[session_physical_reads] [bigint] NOT NULL,
[session_writes] [bigint] NOT NULL,
[tempdb_allocations_mb] [decimal](38, 2) NULL,
[memory_usage] [int] NOT NULL,
[estimated_completion_time] [bigint] NULL,
[percent_complete] [real] NULL,
[deadlock_priority] [int] NULL,
[transaction_isolation_level] [varchar](33) NOT NULL,
[degree_of_parallelism] [smallint] NULL,
[last_dop] [bigint] NULL,
[min_dop] [bigint] NULL,
[max_dop] [bigint] NULL,
[last_grant_kb] [bigint] NULL,
[min_grant_kb] [bigint] NULL,
[max_grant_kb] [bigint] NULL,
[last_used_grant_kb] [bigint] NULL,
[min_used_grant_kb] [bigint] NULL,
[max_used_grant_kb] [bigint] NULL,
[last_ideal_grant_kb] [bigint] NULL,
[min_ideal_grant_kb] [bigint] NULL,
[max_ideal_grant_kb] [bigint] NULL,
[last_reserved_threads] [bigint] NULL,
[min_reserved_threads] [bigint] NULL,
[max_reserved_threads] [bigint] NULL,
[last_used_threads] [bigint] NULL,
[min_used_threads] [bigint] NULL,
[max_used_threads] [bigint] NULL,
[grant_time] [varchar](20) NULL,
[requested_memory_kb] [bigint] NULL,
[grant_memory_kb] [bigint] NULL,
[is_request_granted] [varchar](39) NOT NULL,
[required_memory_kb] [bigint] NULL,
[query_memory_grant_used_memory_kb] [bigint] NULL,
[ideal_memory_kb] [bigint] NULL,
[is_small] [bit] NULL,
[timeout_sec] [int] NULL,
[resource_semaphore_id] [smallint] NULL,
[wait_order] [varchar](20) NULL,
[wait_time_ms] [varchar](20) NULL,
[next_candidate_for_memory_grant] [varchar](3) NOT NULL,
[target_memory_kb] [bigint] NULL,
[max_target_memory_kb] [varchar](30) NULL,
[total_memory_kb] [bigint] NULL,
[available_memory_kb] [bigint] NULL,
[granted_memory_kb] [bigint] NULL,
[query_resource_semaphore_used_memory_kb] [bigint] NULL,
[grantee_count] [int] NULL,
[waiter_count] [int] NULL,
[timeout_error_count] [bigint] NULL,
[forced_grant_count] [varchar](30) NULL,
[workload_group_name] [sysname] NULL,
[resource_pool_name] [sysname] NULL,
[context_info] [varchar](128) NULL,
[query_hash] [binary](8) NULL,
[query_plan_hash] [binary](8) NULL,
[sql_handle] [varbinary] (64) NULL,
[plan_handle] [varbinary] (64) NULL,
[statement_start_offset] INT NULL,
[statement_end_offset] INT NULL
)
INSERT INTO #BlitzWhoResult
EXEC [dbo].[sp_BlitzWho] @ShowSleepingSPIDs = 1, @ExpertMode = 1, @MinElapsedSeconds = 1
SELECT [program_name],
[session_id],
CASE WHEN [query_text] LIKE 'FETCH API_CURSOR%'
THEN CursorQuery(session_id)
ELSE query_text
END AS [query_text],
[query_plan],
[fix_parameter_sniffing] AS [drop_cached_plan_sql],
[status],
[wait_info],
[login_name]
from #BlitzWhoResult
where database_name = 'PUT_YOUR_DATABASENAME_HERE' -- and... add more filters?
DROP TABLE #BlitzWhoResult
END
所以.. 我真的很喜欢 Brents 工具以及他的视频和幽默感