我在Windows Server 2012中使用SQL Server 2014 Enterprise。
我已检查Min
并且Max Allocated Memory for SQL Server
已正确配置。
昨天,用户多次并行报告并收到大量警报(高CPU和高内存)。从下面的查询中,我发现顶级CPU使用了查询:
...
...
FROM sys.dm_exec_query_stats AS qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) AS st
cross apply sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY (total_worker_time/execution_count) desc, qs.last_execution_time DESC
我发现前10个查询完全相同,只是WHERE子句中的更改很少。 execution_count = 1
表示所有查询。查询将记录插入到#temp表中,格式如下:
Insert into #Temp(col1, col2,............)
Select
.
.
From
(
Select
.
.
Where (CONTAINS(val1, ' "xx1*" ') OR CONTAINS(val2, ' "yy1*" ') OR CONTAINS(val3, ' "zz1*" ')..........30-35 CONTAIN blocks)
-- here "xx*", "yy*" values are changing in each query (I guess this is due to parameter selection by end users)
) x
如果这些动态查询是罪魁祸首,那么解决方案是什么(因为用户不会停止运行查询)?
我可以要求将报告查询转换为SP吗? 如何避免我得到的不同执行计划?
我手动杀死了高度利用的查询,但这不是解决方案。
寻求帮助。
更新
我再也看不到任何内存问题了。但CPU仍然达到100%。
我观察到上述特定查询(在报告中使用)经常由用户访问,并且当此查询运行时CPU利用率达到100%。它经常发生。 WHERE子句根据用户的报告参数选择每次执行都会更改(我不知道报告的设计方式或参数的传递方式)。
此外,我已检查表统计信息(每天更新),索引正确定义。基表处理超过3百万行(val1,val2 ...在CONTAIN中使用属于此表)。
调整此查询的方法有哪些?
答案 0 :(得分:1)
显然你的SQL语句没有被缓存,因此你每次都会得到一个新的执行计划。并查看您的代码(除非您已经省略了其他一些块),这可能是因为如果WHERE中的CONTAINS子句。
我的建议是将这些语句转换为存储过程并从WHERE中删除CONTAINS,并通过INNER JOIN到CONTAINSTABLE(...)来完成。看看您是否设法在这些更改后缓存查询。
对于高CPU / RAM使用率,您说用户并行运行报告,因此这听起来像锁定问题。尝试将WITH NOLOCK提示添加到SELECT语句中,看看它是如何进行的。
您也没有说明您的报告声明对哪些数据进行了操作。你在选择数百万条记录吗?由于各种一对多或类似的连接,您是否获得记录乘法?请评论。
<强>更新强>
在OP表示该查询适用于具有3M +记录的表格并且有大约30-35个全文搜索条件后,主要建议是:答案 1 :(得分:0)
我想建议启用服务器级别配置:“针对临时工作负载进行优化”
sp_configure 'optimize for ad hoc workloads',1
GO
reconfigure
go