如何清除 SQL Server 查询缓存?

Posted

技术标签:

【中文标题】如何清除 SQL Server 查询缓存?【英文标题】:How can I clear the SQL Server query cache? 【发布时间】:2010-12-24 18:53:55 【问题描述】:

我有一个针对 SQL Server 2005 运行的简单查询

SELECT * 
FROM Table 
WHERE Col = 'someval'

我第一次执行查询可以取> 15 secs。后续执行返回< 1 sec

如何让 SQL Server 2005 不使用任何缓存结果?我试过跑步

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

但这似乎对查询速度没有影响(还是< 1 sec)。

【问题讨论】:

复制:***.com/questions/1856966/… 但更好 这能回答你的问题吗? How to let SQL Server know not to use Cache in Queries? 【参考方案1】:
EXEC sys.sp_configure N'max server memory (MB)', N'2147483646'
GO
RECONFIGURE WITH OVERRIDE
GO

您为服务器内存指定的值并不重要,只要它与当前的不同即可。

顺便说一句,导致加速的不是查询缓存,而是数据缓存。

【讨论】:

【参考方案2】:

这里有一些很好的解释。看看吧。

http://www.mssqltips.com/tip.asp?tip=1360

CHECKPOINT; 
GO 
DBCC DROPCLEANBUFFERS; 
GO

来自链接的文章:

如果所有性能测试都在 SQL Server 中进行,最好的方法可能是发出 CHECKPOINT,然后发出 DBCC DROPCLEANBUFFERS 命令。尽管 CHECKPOINT 进程是 SQL Server 中的自动内部系统进程并且定期发生,但发出此命令以将当前数据库的所有脏页写入磁盘并清理缓冲区非常重要。然后可以执行 DBCC DROPCLEANBUFFERS 命令从缓冲池中删除所有缓冲区。

【讨论】:

一个可能还包括 DBCC FREEPROCCACHE 当使用 dropcleanbuffers 时,这适用于连接到数据库的每个人,还是仅适用于该用户? @Kris:DBCC DROPCLEANBUFFERS,从缓冲池中删除所有干净的缓冲区。这是查询性能调整的必要步骤,不应在实时 SQL Server 上使用它。 这适用于 SQL Server,但请注意,这在 SQL Azure 中不起作用 - 我在下面发布了一个替代解决方案来处理 SQL Azure 场景。 好,这是唯一真正有效的命令,尝试了许多其他命令,但没有成功。【参考方案3】:

虽然这个问题有点老了,但这可能仍然有帮助。我遇到了类似的问题,使用下面的选项对我有帮助。不确定这是否是永久解决方案,但目前正在修复它。

OPTION (OPTIMIZE FOR UNKNOWN)

那么你的查询会是这样的

select * from Table where Col = 'someval' OPTION (OPTIMIZE FOR UNKNOWN)

【讨论】:

关键字“OPTION”附近的语法不正确。或“未知”附近的语法不正确。 @pabrams 这些在您的查询之后(作为一部分)如下所示:select * from Table where Col = 'someval' OPTION (OPTIMIZE FOR UNKNOWN) 请绝对确保您不会无意中将此类内容放入 PRODUCTION 代码中 - 因为这可能会导致未来出现重大问题。 OPTIMIZE FOR UNKNOWN 会忽略缓存的计划。相反,在生成计划时,它会指示 SQL 服务器选择“平均分布值,独立于任何 [自动] 参数化”来决定要创建什么计划 - 这会导致计划在非统一统计数据中更加一致。一个 OPTION (RECOMPILE) 创建一个 new 计划,但不会清理/释放数据缓存 - 这通常会以计划重新生成和计划缓存成本为代价生成更理想的计划。【参考方案4】:

请注意,SQL Azure/SQL 数据仓库既不支持 DBCC DROPCLEANBUFFERS; 也不支持 DBCC FREEPROCCACHE;

但是,如果您需要在 SQL Azure 中重置计划缓存,您可以更改查询中的一个表(例如,只需添加然后删除一列),这将产生删除计划的副作用从缓存中。

我个人这样做是为了测试查询性能而无需处理缓存计划。

More details about SQL Azure Procedure Cache here

【讨论】:

这对我不起作用,所以计划没有改变。请看这里***.com/questions/46987785/… 经过测试,似乎增删列对缓存没有影响。 以上两个 cmets 看起来这不是一个有效的答案,但它确实是。我刚刚在 SQL 数据库中添加和删除了一个列,执行时间从一分钟多下降到几秒钟。 (虽然已经说过它很快就会恢复到超过一分钟...... - 即使 ARITHABORT ON)【参考方案5】:

清除计划缓存的八种不同方法

1。从整个实例的计划缓存中删除所有元素

DBCC FREEPROCCACHE;

使用它来仔细清除计划缓存。例如,释放计划缓存会导致重新编译存储过程,而不是从缓存中重用。这可能会导致查询性能突然暂时下降。

2。刷新整个实例的计划缓存并抑制常规完成消息

“DBCC 执行完成。如果 DBCC 打印错误消息,请联系您的系统管理员。”

DBCC FREEPROCCACHE WITH NO_INFOMSGS;

3。刷新整个实例的临时和准备好的计划缓存

DBCC FREESYSTEMCACHE ('SQL Plans');

4。刷新一个资源池的临时和准备好的计划缓存

DBCC FREESYSTEMCACHE ('SQL Plans', 'LimitedIOPool');

5。刷新一个资源池的整个计划缓存

DBCC FREEPROCCACHE ('LimitedIOPool');

6。从一个数据库的计划缓存中删除所有元素(在 SQL Azure 中不起作用)

-- Get DBID from one database name first
DECLARE @intDBID INT;
SET @intDBID = (SELECT [dbid] 
                FROM master.dbo.sysdatabases 
                WHERE name = N'AdventureWorks2014');

DBCC FLUSHPROCINDB (@intDBID);

7。清除当前数据库的计划缓存

USE AdventureWorks2014;
GO
-- New in SQL Server 2016 and SQL Azure
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;

8。从缓存中删除一个查询计划

USE AdventureWorks2014;
GO

-- Run a stored procedure or query
EXEC dbo.uspGetEmployeeManagers 9;

-- Find the plan handle for that query 
-- OPTION (RECOMPILE) keeps this query from going into the plan cache
SELECT cp.plan_handle, cp.objtype, cp.usecounts, 
DB_NAME(st.dbid) AS [DatabaseName]
FROM sys.dm_exec_cached_plans AS cp CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS st 
WHERE OBJECT_NAME (st.objectid)
LIKE N'%uspGetEmployeeManagers%' OPTION (RECOMPILE); 

-- Remove the specific query plan from the cache using the plan handle from the above query 
DBCC FREEPROCCACHE (0x050011007A2CC30E204991F30200000001000000000000000000000000000000000000000000000000000000);
 

来源123

【讨论】:

以上是关于如何清除 SQL Server 查询缓存?的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 2012 中缓存并进行查询 - 我可以假设啥以及如何使用此缓存?

SQL Server2008优化之SET STATISTICS开关

如何清除Oracle中的所有缓存项

SQL Server的优化器会缓存标量子查询结果集吗

Java JOOQ 与 SQL Server:缓存查询

Sql Server中执行计划的缓存机制