标签: plan-cache

SQL SERVER 2016 高 CPU

我有一台装有 SQL Server 2016 的全新服务器。

它有 24 个 CPU,大约 80go 的 RAM。

问题是,有时,CPU 会变得非常高(> 70%),而没有任何具体原因。

如果我查看“execute sp_WhoIsActive @get_locks=1”,我会运行大约 40 个查询,但没有锁定,其中一些查询超过 30 秒而不是几毫秒。

这在生产中大约每天附加一次。到目前为止,我唯一的解决方法是将选项“并行成本阈值”从 90 更改为 89,从 89 更改为 90。更改此值实际上可以在不到 10 秒的时间内解决问题,并且 CPU 费用越来越低,并且我的用户更快乐。

你们知道这个问题的根源吗?我已经考虑过计划缓存,但我不知道如何处理这个想法......

编辑:我已禁用英特尔超线程,但问题仍然存在。我已经安排了一个每小时清理缓存的任务。你有什么主意吗 ?

编辑 2:我在 Microsoft 支持上打开了一个问题。显然,重新启动 SQL Server 2016 解决了页面保留问题。如果我有一个“真正的”修复程序,我会尽快通知您。

performance parallelism plan-cache sql-server-2016

5
推荐指数
1
解决办法
3530
查看次数

清除计划缓存后如何重新生成执行计划?

清除 SQL Server 上的计划缓存后,如何重新生成存储过程的执行计划而不执行存储过程本身?

当我今天早上更新统计数据时,我的一个存储过程运行得非常缓慢。根据一些谷歌,我发现清除计划缓存可以解决这个问题 - 确实如此。但是,如果我必须再次执行此操作,我希望避免在用户等待响应时重新生成计划对性能造成影响。

SQL Server 的版本/版本是 2016 Enterprise。

sql-server execution-plan plan-cache sql-server-2016

5
推荐指数
1
解决办法
1898
查看次数

SQL Server 缓存了在某些情况下不是最佳的执行计划,并将其用于所有后续查询

我们的应用程序使用 SQL Server 2014,我们遇到了与计划缓存相关的问题。

我们有一个参数化查询,它的执行计划取决于参数值。服务器缓存在某些情况下不是最佳的执行计划,然后将其用于所有后续查询。

细节:

我们有一个由以下列组成的表:

(
 [Revision] [bigint] IDENTITY(1,1) NOT NULL,
 [UserId] [uniqueidentifier] NOT NULL,
 ...A WHOLE LOT OF OTHER COLUMNS...
)
Run Code Online (Sandbox Code Playgroud)

这两列的含义很清楚,UserId是记录所属用户的Id,是记录Revision的自增索引。其他列并不重要,但它们存在并影响执行计划。

该表包含 ~40.000.000 行和 ~200.000 个不同UserId值,因此每个用户平均有 200 条记录。行永远不会更新,我们只使用 INSERT 和 DELETE 来修改数据。

我们的应用程序对此表执行以下查询:

SELECT * FROM SampleTable WHERE Revision > {someRevision} AND UserId = {someId}
Run Code Online (Sandbox Code Playgroud)

该表有两个索引:

  1. 聚集索引: Revision asc
  2. 非聚集索引: UserId asc, Revision asc

当我手动执行此查询时,我看到执行计划取决于someRevision.

  • 如果是比较接近的修订目前的最高值,则服务器使用Clustered Index SeekSeek Predicate: Revision > someRevision

  • 如果它没有关闭,服务器使用Index Seek …

index sql-server execution-plan plan-cache

5
推荐指数
1
解决办法
1759
查看次数

解决 sp_Blitz 发现:一个查询的多个计划

在此处输入图片说明

为什么一个查询的多个计划不好

所以我跑去sp_Blitz处理一些系统。有一些代码可以像往常一样清理。一些应该是聚集索引的堆。等等。

这个特定的查询使用了文字,似乎产生了很多计划。在此查询中的表上整理了索引和内容,甚至为最新的代码/数据库将查询参数化以投入生产。

但是查询仍然显示为参数化问题。(DBA 帮助将计划缓存查询转换为 SSRS 报告,因此我可以从浏览器在 PROD 环境中快速运行它们)。

然后去哪儿?忽略它?(似乎很多计划都很重要)

使用强制参数化?(但显式参数化的那个出现了)。

呃 - 我看到开发人员没有接受我的建议,认为它LEFT JOIN正在变成INNER JOIN......我必须把它修好......

如果没有强制参数化,所有这些文字样式的查询将永远不会共享相同的计划吗?这个查询对于简单的参数化是否太复杂

sql-server plan-cache sql-server-2014 sp-blitz

5
推荐指数
0
解决办法
221
查看次数

为什么查询缓存计划保留动态查询而不保留 sp?

我的公司有一些使用大量动态查询(无参数)的遗留系统。在较新的系统中,我们使用存储过程和参数化 SQL。然而,我们发现我们的存储过程经常出现性能峰值。

我查看了它,似乎计划缓存会定期清除存储过程计划,但在计划缓存中保留了大量动态 SQL 语句。

我对 SQL Server (SQL Server 2017) 这样做的原因有点困惑。SQL Server 如何决定删除哪一个?

sql-server execution-plan plan-cache

4
推荐指数
1
解决办法
372
查看次数

由于 sp_executesql 的许多参数导致存储过程编译阻塞

我看到由于编译特定存储过程时的锁定而导致阻塞(如KB 263889 中所述)。基本上,有几个进程在同一个资源“TAB:8:1044511100:0 [COMPILE]”上等待 LCK_M_X,如果我查找对象,它就是我的存储过程之一。

试图缩小为什么不缓存该过程的执行计划的范围,我发现sp_executesql的@params 参数的大小是一个因素:如果@params 超过 4000 个字符,有时执行计划会被缓存,但是如果@params 为 4000 个字符或更少,则每次都会缓存计划。

这可以通过以下过程重现:

CREATE PROCEDURE [dbo].ObviouslyAnonymizedProcedure (
      @SchemaId int = Null
    , @TypeDesc varchar(60) = Null
    , @paramFoo varchar(100) = null
    , @paramBar datetime2(4) = null
    , @paramBaz numeric(4,3) = null
    -- Parameter names have been changed.  I added a "param" prefix and set type
    -- varchar(100) to more easily get up to 4000 characters in this example.
    , @paramQux varchar(100) = null
    , @paramQuux …
Run Code Online (Sandbox Code Playgroud)

sql-server stored-procedures sql-server-2008-r2 plan-cache

3
推荐指数
1
解决办法
1218
查看次数

在计划缓存中找不到编译的参数值

我发现,通过查询存储,一个查询平均执行 297582 次逻辑读取。

我想看看我是否能够稍微调整该查询,然后尝试再次执行该查询以查看是否有任何改进。

问题是我在缓存计划中找不到编译参数值。

我错过了什么吗?也许是一些阻止参数值缓存的原因/设置?

即使我以 XML 格式打开执行计划,我也找不到参数。

附加信息:查询由第三方应用程序执行,该应用程序准备语句,然后使用sp_prepare和执行它们sp_execute

完整的 XML 计划

查询存储:在属性选项卡中找不到任何参数

计划缓存 DMV:计划缓存 dmv

sql-server execution-plan parameter plan-cache sql-server-2016

3
推荐指数
1
解决办法
287
查看次数

sp_Blitz,>1000 个 CREATE PROCEDURE 计划

我正在使用Brent Ozar 的sp_Blitz,其结果之一是:

一个查询的多个计划

计划缓存中的单个查询有 1146 个计划 - 这意味着我们可能存在参数化问题。

结果中链接有这个查询:

SELECT q.PlanCount,
q.DistinctPlanCount,
qs.query_hash,
st.text AS QueryText,
qp.query_plan AS QueryPlan
FROM ( SELECT query_hash,
COUNT(DISTINCT(query_hash)) AS DistinctPlanCount,
COUNT(query_hash) AS PlanCount
FROM sys.dm_exec_query_stats
GROUP BY query_hash
) AS q
JOIN sys.dm_exec_query_stats qs ON q.query_hash = qs.query_hash
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) AS qp
WHERE PlanCount > 1
ORDER BY q.PlanCount DESC, q.query_hash;
Run Code Online (Sandbox Code Playgroud)

...它显示了计划数量最多的查询。

当我运行它时,我得到的最重要的结果之一(对于相同的查询哈希有大约 1150 个计划)让我感到困惑:

查询结果

也许在屏幕截图上有点难以识别 -这是一个完整的CREATE …

sql-server plan-cache sql-server-2016 sp-blitz

3
推荐指数
2
解决办法
660
查看次数

将 sys.dm_exec_sql_text 中的相似查询组合在一起

我正在分析支持 3rd 方应用程序的 2008 实例。

该应用程序将生成 SQL 代码,然后将其作为临时查询发送到数据库。

我正在使用此查询(基于 Glenn Berry 脚本):

SELECT
    qs.creation_time
    ,qs.last_execution_time
    ,qs.execution_count
    ,qs.total_worker_time
    ,qs.total_physical_reads
    ,qs.total_logical_writes
    ,qs.total_logical_reads
    ,qs.plan_handle
    ,qt.text
    ,qt.dbid
FROM 
        sys.dm_exec_query_stats AS qs WITH (NOLOCK)
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE
    qt.dbid >= 7
OPTION (RECOMPILE)
Run Code Online (Sandbox Code Playgroud)

我的问题是我正在为非常相似的查询获得数千个计划,即

SELECT * FROM customers WHERE name = 'bob'
SELECT * FROM customers WHERE name = 'bill'
Run Code Online (Sandbox Code Playgroud)

(实际上查询非常大,最多 3000 个字符)

这使得将数据转换为适合高级分析的格式几乎是不可能的。

是否可以快速比较 2 个 SQL 查询并查看它们是否几乎相同?然后我会随机选择其中一个查询,并将所有活动与该查询进行分组。(我试过 DIFFERENCE 但速度很慢)

SQL 是否已经存储了一个类似于 MD5 Hash sql_handle 的值,它允许它查看两个查询是否相似并因此重用相同的计划?(如果存在这样的值,那么我会对此进行分组)

我对存储过程没有这个问题,因为正在重用相同的计划。我只想将所有类似的临时人员组合在一起。

sql-server-2008 sql-server dmv plan-cache

3
推荐指数
1
解决办法
153
查看次数

创建许多计划的参数化查询

我有一些参数化的查询,但它们每次仍在创建一个新的执行计划。我正在使用 SQL Server 2016。

查询如下:

(@P1 varchar(1043),@P2 varchar(6))
UPDATE table 
SET FILEDATA=@P1 
WHERE FILEID=@P2
Run Code Online (Sandbox Code Playgroud)

这个查询没有使用缓存中已经生成的执行计划,而是每次都创建一个新计划。

此图显示了单个查询正在创建的计划计数以及查询

sql-server execution-plan parameter plan-cache

3
推荐指数
1
解决办法
638
查看次数