sql-server – sql server plan cache中的ad hoc和准备好的查询有什么区别?

我正在尝试了解sql server的计划缓存内容.

所以我的问题是:
1.临时计划和准备计划有什么区别?
2.在尝试优化sql server计划缓存时,我应该知道什么?

最佳答案

What is the difference between ad hoc and prepared plans?

特设查询:

select * from t1

准备好的查询:
用占位符代替实际值的查询称为准备语句.

一些例子:

select * from t1 where id=@id

还有一个来自维基百科的例子:

command.CommandText = "SELECT * FROM users WHERE USERNAME = @username AND ROOM = @room";

    command.Parameters.AddWithValue("@username", username);
    command.Parameters.AddWithValue("@room", room);

What should I know about it when trying to optimize the sql server plan cache?

有关于如何优化计划缓存的白皮书.所以我会尽量保持它…

通常,当针对SQL执行查询时,SQL会编译计划并将其存储在计划缓存中.此计划缓存是从缓冲池中获取的内存,不同版本对how much amount of memory will be used具有不同的限制

你知道内存是一种宝贵的资源,如果你有泄漏,没有多少硬件就足够了..

假设您只提交一次或两次查询,并且您倾向于提交这样的查询很多.SQL会将此查询的计划存储在计划缓存中,这通常会导致PlanCache这很糟糕

有不同的DMVS可以帮助您挖掘计划缓存..

查找不同类型的对象的计划在计划缓存中:

select 
objtype,count(*) as countt,sum(size_in_bytes)*1024.0 as memoryinkb
 from   sys.dm_exec_cached_plans a
 group by objtype

特别的,准备好的查询是膨胀的plancache并且只使用一次:

select q.query_hash, 
    q.number_of_entries, 
    t.text as sample_query, 
    p.query_plan as sample_plan
from (select top 20 query_hash, 
            count(*) as number_of_entries, 
            min(sql_handle) as sample_sql_handle, 
            min(plan_handle) as sample_plan_handle
        from sys.dm_exec_query_stats
        group by query_hash
        having count(*) > 1
        order by count(*) desc) as q
    cross apply sys.dm_exec_sql_text(q.sample_sql_handle) as t
    cross apply sys.dm_exec_query_plan(q.sample_plan_handle) as p

要删除膨胀计划缓存的语句:

DECLARE @MB decimal(19,3)
        , @Count bigint
        , @StrMB nvarchar(20)


SELECT @MB = sum(cast((CASE WHEN usecounts = 1 AND objtype IN ('Adhoc', 'Prepared') THEN size_in_bytes ELSE 0 END) as decimal(12,2)))/1024/1024 
        , @Count = sum(CASE WHEN usecounts = 1 AND objtype IN ('Adhoc', 'Prepared') THEN 1 ELSE 0 END)
        , @StrMB = convert(nvarchar(20), @MB)
FROM sys.dm_exec_cached_plans


IF @MB > 10
        BEGIN
                DBCC FREESYSTEMCACHE('SQL Plans') 
                RAISERROR ('%s MB was allocated to single-use plan cache. Single-use plans have been cleared.', 10, 1, @StrMB)
        END
ELSE
        BEGIN
                RAISERROR ('Only %s MB is allocated to single-use plan cache – no need to clear cache now.', 10, 1, @StrMB)
                — Note: this is only a warning message and not an actual error.
        END
go

以上内容应该让您了解从哪里开始,下面是必读的主题和参考:

1.http://www.sqlskills.com/blogs/kimberly/category/plan-cache/

2.http://sqlblog.com/blogs/kalen_delaney/archive/2007/11/04/did-you-know-sp2-does-not-limit-the-amount-of-plan-cache-you-can-have.aspx

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

4.Must read article By SQLCAT on issues customer faced while using Prepare Statements

在上面的参考文章中,kimberely建议启用Optimy for Adhoc工作负载选项,但我建议先测试它.在DBA.SE上有一个interesting thread

转载注明原文:sql-server – sql server plan cache中的ad hoc和准备好的查询有什么区别? - 代码日志