22,209
社区成员
发帖
与我相关
我的任务
分享
SELECT * FROM sys.syscacheobjects WHERE sql LIKE '%EXEC PROCNAME%'
SELECT * FROM sys.dm_exec_cached_plans A
CROSS APPLY sys.dm_exec_sql_text(plan_handle) B
WHERE B.text LIKE '%EXEC PROCNAME%'
DBCC FREEPROCCACHE(plan_handle)
[/quote]
第二条,我们没有明显的数据划分界限,比如有时候需要按人查,查这个用户下面的数据,有时候要按日期查不管人, 有时候要按区域查 不管人和时间 就是说这些条件都是由自己自己选择的, 这种情况怎么分区? 分区条件是啥?不好分吧。
第三条。 数据变化多大叫大? 目前的增长率是每天多几万条而已,不能改程序,也不要改,因为根本问题我们没有找到,不能把头埋到地里对吧, 另外清除缓存计划更是不可行的招。 因为这种重新编译没区别,更不可能每隔几天就上去清一次, 根本原因还是没有找到
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].Proc_DBA_GetSlowSQL_ByCPU') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].Proc_DBA_GetSlowSQL_ByCPU
GO
-- =============================================
-- Author: yenange
-- Create date: 2015-08-18
-- Description: 取得最近执行占用CPU时间最长的SQL语句
-- =============================================
CREATE PROCEDURE dbo.Proc_DBA_GetSlowSQL_ByCPU
@topNum INT = 50 --取前多少条记录
,@lastExecutionTime DATETIME = NULL --最后执行时间, 默认为NULL. 为 NULL 则忽略此条件; 不为NULL 则取大于此参数之后执行的
,@excludeNight BIT=1 --是否 排除晚上的信息? 默认=1 排除。选择是=1,后面两参数才有意义
,@nightBegin CHAR(5)='22:00' --"晚上"开始时间点, 默认 22:00
,@nightEnd CHAR(5)='06:00' --"晚上"结束时间点, 默认 06:30
,@containSQL NVARCHAR(300)=NULL --语句中包含的SQL. 默认为NULL. 为NULL则忽略此条件; 不为NULL则取包含此参数的记录
AS
BEGIN
SET NOCOUNT ON
DECLARE @nightBegin_num INT
DECLARE @nightEnd_num INT
SET @nightBegin_num=CAST( replace(@nightBegin,':','') AS INT)
SET @nightEnd_num=CAST( replace(@nightEnd,':','') AS INT)
SET ROWCOUNT @topNum
SELECT
st.text AS SQL_Full --父级完整语句
,SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,
((CASE statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE qs.statement_end_offset END
- qs.statement_start_offset)/2) + 1) as SQL_Part --统计对应的部分语句
, CAST( ((qs.total_elapsed_time / 1000000.0)/qs.execution_count) AS DECIMAL(28,2) ) AS [平均消耗秒数]
, CAST(qs.last_elapsed_time / 1000000.0 AS DECIMAL(28, 2)) AS [最后完成消耗秒数]
, qs.last_execution_time AS [最后执行时间]
, CAST(qs.min_elapsed_time / 1000000.0 AS DECIMAL(28, 2)) AS [最小消耗秒数]
, CAST(qs.max_elapsed_time / 1000000.0 AS DECIMAL(28, 2)) AS [最大消耗秒数]
, CAST(qs.total_elapsed_time / 1000000.0 AS DECIMAL(28, 2)) AS [总消耗秒数]
, (qs.execution_count) AS [总执行次数]
, creation_time AS [编译计划的时间]
, CAST(qs.last_worker_time / 1000000.0 AS DECIMAL(28, 2)) AS [最后完成占用CPU秒数]
, sql_handle,statement_start_offset,statement_end_offset
,plan_generation_num,plan_handle,creation_time
,last_execution_time,execution_count
,total_worker_time,last_worker_time,min_worker_time,max_worker_time
,total_physical_reads,last_physical_reads,min_physical_reads,max_physical_reads,total_logical_writes,last_logical_writes,min_logical_writes,max_logical_writes,total_logical_reads,last_logical_reads,min_logical_reads,max_logical_reads
,total_clr_time,last_clr_time,min_clr_time,max_clr_time
from sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
WHERE
--1. 最后执行时间
(@lastExecutionTime IS NULL OR qs.last_execution_time>=@lastExecutionTime)
--2. 包含 SQL 条件
AND
(@containSQL IS NULL OR st.[text] LIKE '%'+@containSQL+'%')
AND
--3. 是否排除晚上
(
@excludeNight=0
OR
(
--2.1 开始大于结束 22:00->6:30 [ x >=6:30(end) and x<22:00(begin) ]
@nightBegin_num>@nightEnd_num AND
(
CAST( replace(CONVERT(varchar(5),last_execution_time,108),':','') AS INT)>=@nightEnd_num
AND
CAST( replace(CONVERT(varchar(5),last_execution_time,108),':','') AS INT)<@nightBegin_num
)
)
OR
(
--2.2 开始小于结束 1:00->6:30 [ x>=0:00 and x<1:00 or x>=6:30 and x<24:00 ]
@nightBegin_num<@nightEnd_num AND
(
(
CAST( replace(CONVERT(varchar(5),last_execution_time,108),':','') AS INT)>=0
AND
CAST( replace(CONVERT(varchar(5),last_execution_time,108),':','') AS INT)<@nightBegin_num
)
OR
(
CAST( replace(CONVERT(varchar(5),last_execution_time,108),':','') AS INT)>=@nightEnd_num
AND
CAST( replace(CONVERT(varchar(5),last_execution_time,108),':','') AS INT)<2400
)
)
)
)
ORDER BY qs.last_worker_time DESC
SET NOCOUNT OFF
SET ROWCOUNT 0
END
GO
EXEC sys.sp_addextendedproperty
@name=N'Version', @value=N'1.1' ,
@level0type=N'SCHEMA',@level0name=N'dbo',
@level1type=N'PROCEDURE',@level1name=N'Proc_DBA_GetSlowSQL_ByCPU'
3. 这个很可能是参数嗅探。
如果这个存储过程执行不是特别频繁(重编译主要使cpu变高), 直接在存储过程后面加:WITH RECOMPILE
CREATE PROCEDURE dbo.Sample_Procedure
@param1 int = 0,
@param2 int
WITH RECOMPILE
AS
SELECT @param1,@param2
RETURN 0
如果频繁, 而且压力较大, 可以参考:
http://www.cnblogs.com/lyhabc/archive/2013/03/02/2941144.html
简单来说, 你可以直接指定索引或者Plan Guide, 使执行计划按走你想要的方式。
SELECT * FROM sys.syscacheobjects WHERE sql LIKE '%EXEC PROCNAME%'
SELECT * FROM sys.dm_exec_cached_plans A
CROSS APPLY sys.dm_exec_sql_text(plan_handle) B
WHERE B.text LIKE '%EXEC PROCNAME%'
DBCC FREEPROCCACHE(plan_handle)