大多数查询计划在过去 4 小时内重新创建

Mar*_*ski 9 performance sql-server sql-server-2012 sp-blitzcache query-performance

我的 SQL Server 数据库的性能有问题。我找到了这个工具sp_BlitzCache。命令执行后,我得到了这个语句:

您在过去 24 小时内创建了 92.00% 的计划,在过去 4 小时内创建了 92.00%。

虽然我发现了问题(使用 SQL Server Profiler,我检查了 StmtRecompile 事件发生),但我只能找到几个经常重建的全文搜索查询。但是,全文搜索查询仅占所有查询的 5% 左右。

您有什么建议可能会导致其余 87% 的计划重新创建?

我有 SQL Server 2012(版本 11.0.6567.0)。

编辑:我添加了我的性能计数器

+---------------------------+--------------------------------+--------------+
|        object_name        |          counter_name          |  cntr_value  |
+---------------------------+--------------------------------+--------------+
| SQLServer:Buffer Manager  | Background writer pages/sec    |            0 |
| SQLServer:Buffer Manager  | Buffer cache hit ratio         |        28436 |
| SQLServer:Buffer Manager  | Buffer cache hit ratio base    |        28436 |
| SQLServer:Buffer Manager  | Checkpoint pages/sec           |      8259452 |
| SQLServer:Buffer Manager  | Database pages                 |      4434337 |
| SQLServer:Buffer Manager  | Free list stalls/sec           |            9 |
| SQLServer:Buffer Manager  | Integral Controller Slope      |            0 |
| SQLServer:Buffer Manager  | Lazy writes/sec                |         5608 |
| SQLServer:Buffer Manager  | Page life expectancy           |       438901 |
| SQLServer:Buffer Manager  | Page lookups/sec               | 122694703703 |
| SQLServer:Buffer Manager  | Page reads/sec                 |     60994608 |
| SQLServer:Buffer Manager  | Page writes/sec                |    126076564 |
| SQLServer:Buffer Manager  | Readahead pages/sec            |     45305420 |
| SQLServer:Buffer Manager  | Target pages                   |    130990080 |
| SQLServer:Buffer Node     | Database pages                 |      4434337 |
| SQLServer:Buffer Node     | Page life expectancy           |       438901 |
| SQLServer:Buffer Node     | Local node page lookups/sec    |            0 |
| SQLServer:Buffer Node     | Remote node page lookups/sec   |            0 |
| SQLServer:Memory Manager  | External benefit of memory     |            0 |
| SQLServer:Memory Manager  | Connection Memory (KB)         |         3304 |
| SQLServer:Memory Manager  | Database Cache Memory (KB)     |     35474784 |
| SQLServer:Memory Manager  | Free Memory (KB)               |     13229808 |
| SQLServer:Memory Manager  | Granted Workspace Memory (KB)  |            0 |
| SQLServer:Memory Manager  | Lock Memory (KB)               |       455928 |
| SQLServer:Memory Manager  | Lock Blocks Allocated          |      1798154 |
| SQLServer:Memory Manager  | Lock Owner Blocks Allocated    |      3568588 |
| SQLServer:Memory Manager  | Lock Blocks                    |        10562 |
| SQLServer:Memory Manager  | Lock Owner Blocks              |        10617 |
| SQLServer:Memory Manager  | Maximum Workspace Memory (KB)  |     43368000 |
| SQLServer:Memory Manager  | Memory Grants Outstanding      |            0 |
| SQLServer:Memory Manager  | Memory Grants Pending          |            0 |
| SQLServer:Memory Manager  | Optimizer Memory (KB)          |         1400 |
| SQLServer:Memory Manager  | Reserved Server Memory (KB)    |            0 |
| SQLServer:Memory Manager  | SQL Cache Memory (KB)          |       229112 |
| SQLServer:Memory Manager  | Stolen Server Memory (KB)      |      8063232 |
| SQLServer:Memory Manager  | Log Pool Memory (KB)           |         4192 |
| SQLServer:Memory Manager  | Target Server Memory (KB)      |     56934400 |
| SQLServer:Memory Manager  | Total Server Memory (KB)       |     56767824 |
| SQLServer:Memory Node     | Database Node Memory (KB)      |     35474784 |
| SQLServer:Memory Node     | Free Node Memory (KB)          |     13229808 |
| SQLServer:Memory Node     | Foreign Node Memory (KB)       |            0 |
| SQLServer:Memory Node     | Stolen Node Memory (KB)        |      8063208 |
| SQLServer:Memory Node     | Target Node Memory (KB)        |     56934376 |
| SQLServer:Memory Node     | Total Node Memory (KB)         |     56767800 |
+---------------------------+--------------------------------+--------------+
Run Code Online (Sandbox Code Playgroud)

The*_*war 6

用于测试计划创建时间的查询是这样的

WITH x AS (
SELECT SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 24 THEN 1 ELSE 0 END) AS [plans_24],
       SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 4 THEN 1 ELSE 0 END) AS [plans_4],
       SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 1 THEN 1 ELSE 0 END) AS [plans_1],
       COUNT(deqs.creation_time) AS [total_plans]
FROM sys.dm_exec_query_stats AS deqs
)
SELECT CONVERT(DECIMAL(3,2), NULLIF(x.plans_24, 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_24],
       CONVERT(DECIMAL(3,2), NULLIF(x.plans_4 , 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_4],
       CONVERT(DECIMAL(3,2), NULLIF(x.plans_1 , 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_1],
       @@SPID AS SPID
INTO #plan_creation
FROM x
OPTION (RECOMPILE) ;
Run Code Online (Sandbox Code Playgroud)

SP 还提供了一些线索以及从哪里开始您的进一步研究

如果这些百分比很高,则可能是内存压力或计划缓存不稳定的迹象

除了上述线索,请检查您的服务器是否已重新启动。

如果您的服务器没有重新启动,那么下面是我将采取的方法

  • 检查您是否面临记忆压力

首先看看,如果你的内存设置是最佳配置。如果是这样,你可以使用下面的计数器来查看你是否面临内存压力

内存:可用 MB
SQL 缓冲区:可用页面
SQL 缓冲区:页面寿命
SQL 缓冲区:延迟写入

如果您面临内存压力,那么您可以查看并调整使用更多内存的查询或尝试添加更多内存

您可能运行过导致重新编译的 查询。其中一些包括

  • 对查询引用的表或视图所做的更改(ALTER TABLE 和 ALTER VIEW)。

  • 对单个过程所做的更改,这将从缓存中删除该过程的所有计划 (ALTER PROCEDURE)。

  • 对执行计划使用的任何索引的更改

  • 执行计划使用的统计信息的更新,从语句显式生成,例如 UPDATE STATISTICS,或自动生成。

  • 删除执行计划使用的索引。

您还可以查看此白皮书以了解有关计划缓存的更多详细信息

https://technet.microsoft.com/en-us/library/ee343986(v=sql.100).aspx