【SQL Server学习笔记】索引调优、统计信息、查询调整、资源调控

来源:互联网 发布:查看系统版本 linux 编辑:程序博客网 时间:2024/05/29 01:52

管理索引时需要注意的问题:

A、标识出索引碎片。指出了应该对哪些索引进行重新生成或重新组织。

B、显示出索引的使用情况。可以指出哪些索引没有使用过。

 

建立索引的基本规则:

A、针对优先级高的、使用频繁的查询来增加索引,同时测试查询看索引是否被使用,并且不要同时增加多个索引。

 

B、除非有非常好的原因,否则在每一个表都增加一个聚集索引。

 

C、选择很少改变的、高度唯一的、数据类型占用字节少的列做为聚集索引键。非聚集索引应该建立在包含高度唯一数据的列上,基于查询中的应用挑选列,特别是在join和where子句中的列,为非键列考虑使用include。基于使用的查询来预估需要哪些索引,然后通过数据库引擎优化顾问工具来评估这些索引。

 

D、随着数据和应用程序活动的改变,索引的性能和效能也会改变,所以要监视查询性能。特别是索引碎片化会降低查询性能,返回相同的结果需要更多的IO操作,通过重新生成、重新组织索引来保持索引碎片最小化。

 

E、为只读文件组或数据库上的索引使用100%填充因子,这样使得完成查询需要访问的数据页更少,相应的IO操作也更少,效率自然得到提升。

 

1、索引碎片 

/*=======================================================注意:所有的参数都是以当前数据库来计算的,所以必须指定完全限定。模式影响如何收集碎片数据:LIMITED:扫描堆所有的页,对于索引,只扫描叶级别上面的父级别页SAMPLED:收集堆或索引中1%采样率的数据DETAILED:扫描所有页,最精确但速度最慢当制定null或default时,等同于limited模式。===================================================*/select DB_NAME(d.database_id),    OBJECT_NAME(d.object_id),        i.name,        --索引名称    d.index_type_desc,    d.alloc_unit_type_desc,        d.index_depth,  --索引的深度    d.index_level,  --索引当前级别        --索引的逻辑碎片,或 IN_ROW_DATA 分配单元中堆的区碎片    d.avg_fragmentation_in_percent,        --IN_ROW_DATA分配单元的叶级别中的碎片数    d.fragment_count,        --IN_ROW_DATA 分配单元的叶级别中的一个碎片的平均页数    d.avg_fragment_size_in_pages,        --对于索引,平均百分比应用于 IN_ROW_DATA 分配单元中 b 树的当前级别    --对于堆,表示 IN_ROW_DATA 分配单元中所有数据页的平均百分比    d.avg_page_space_used_in_percent,        d.page_count,               --索引或数据页的总数    d.record_count,             --总记录数    d.min_record_size_in_bytes, --最小记录大小(字节)    d.max_record_size_in_bytes, --最大记录大小(字节)    d.avg_record_size_in_bytes, --平均记录大小(字节)        --压缩页的数目    d.compressed_page_count,        --分配单元中将被虚影清除任务删除的虚影记录数    d.ghost_record_count,    --由分配单元中未完成的快照隔离事务保留的虚影记录数    d.version_ghost_record_count,    --堆中具有指向另一个数据位置的转向指针的记录数    d.forwarded_record_count         from sys.dm_db_index_physical_stats   (db_id('wcc'),   --数据库id    null,           --对象id:数据库名称.架构.对象名称    null,           --索引id    null,           --分区号    ''              --模式   )dinner join sys.indexes i        on d.object_id = i.object_id           and d.index_id = i.index_id

 2、索引使用情况

create table txt(id int primary key,v varchar(10))create index idx_txt_v on txt (v)insert into txtvalues(1,'a'),      (2,'b'),      (3,'c')select vfrom txt--idx_txt_v索引中的user_scans会显示1--user_updates会显示1select DB_NAME(d.database_id),OBJECT_NAME(d.object_id),i.name,user_seeks,user_scans,user_lookups,user_updates  --通过用户查询执行的更新次数  from sys.dm_db_index_usage_stats dinner join sys.indexes i    on d.object_id = i.object_id       and d.index_id = i.index_idwhere database_id = DB_ID('test2')--添加数据后,user_updates会显示2insert into txtvalues(4,'a'),      (5,'b'),      (6,'c')


丢失的索引

SELECT TOP 30         ROUND(s.avg_total_user_cost * s.avg_user_impact * ( s.user_seeks                                                             + s.user_scans ),               0) AS [Total Cost] ,         s.avg_total_user_cost * ( s.avg_user_impact / 100.0 ) * ( s.user_seeks                                                               + s.user_scans ) AS Improvement_Measure ,         DB_NAME() AS DatabaseName ,         d.[statement] AS [Table Name] ,         equality_columns ,         inequality_columns ,         included_columns FROM    sys.dm_db_missing_index_groups g         INNER JOIN sys.dm_db_missing_index_group_stats s ON s.group_handle = g.index_group_handle         INNER JOIN sys.dm_db_missing_index_details d ON d.index_handle = g.index_handle WHERE   s.avg_total_user_cost * ( s.avg_user_impact / 100.0 ) * ( s.user_seeks                                                               + s.user_scans ) > 10 ORDER BY [Total Cost] DESC ,         s.avg_total_user_cost * s.avg_user_impact * ( s.user_seeks                                                       + s.user_scans ) DESC

3、统计信息

一个问题:

SQL Server的统计信息
我知道统计信息是为查询引擎做查询计划用的,现在有以下请教大家,谢谢!

1.统计信息是什么时候会自动建立与更新,Insert、update、delete时候会自动更新统计信息吗?

2.当我把数据库设置中的"自动创建统计信息"与"自动更新统计信息"设置为True,我还需要建立维护计划中建立计划维护统计信息吗?此处的自动建立与更新在什么时候会自动更新?

3.当我修改表结构与dbcc dbreindex时都会自动更新表或view的统计信息吗?

4.统计信息更新与建立时是生成一些什么信息?


我的回复:

1、只要你在数据库设置中的"自动创建统计信息"与"自动更新统计信息"设置为True,那么在语句执行时,不管是update、delete、还是select语句,就会根据where条件中的字段,自动设置统计信息。
但insert 语句运行时,应该不会建立统计信息。

2、虽然设置了自动更新或创建统计信息的设置为true,但是所谓自动更新统计信息,是按照你对数据修改的数量来决定的,sql server有一些内部的判断条件,比如修改的数据占到整个表的百分之多少后,才会更新统计信息,这个不是很准确的。
所以还是需要你通过,update statistics 表 来更新统计信息。

3、如果你没有删除那个统计信息涉及到的列,应该不会重新生成。

4、通过:dbcc show_statistics('表',统计名称)


呵呵,我做了一个实验,你可以看看。
下面的代码,需要一步一步运行,前后对比:

--1.建表select * into tb_objectfrom sysobjects--2.查询统计信息,发现还没有创建select *from sys.statswhere object_id = object_id('tb_object')--3.通过where条件查询1条记录select *from tb_objectwhere ID = 3--4.发现,已经创建了统计信息select *from sys.statswhere object_id = object_id('tb_object')/*object_idnamestats_idauto_createduser_createdno_recomputehas_filterfilter_definition389576426_WA_Sys_00000002_173876EA21000NULL*/--5.这个统计信息,到底是什么东东呢?dbcc show_statistics('tb_object',               --表名                     _WA_Sys_00000002_173876EA  --统计信息的名称                    )/*NameUpdatedRowsRows SampledStepsDensityAverage key lengthString IndexFilter ExpressionUnfiltered Rows_WA_Sys_00000002_173876EA11 11 2013  1:14PM59594214NO NULL59All densityAverage LengthColumns0.016949154idRANGE_HI_KEYRANGE_ROWSEQ_ROWSDISTINCT_RANGE_ROWSAVG_RANGE_ROWS30101711118010117010119010123010125111129111134010141010144010146010149010151111154010155010158010160111164010165010169212173212175111178010182010185010190010192111194111196111198111153575229010169575286010118157568501012295758560101373576369010138957642601011977058079010120090581931111204105830711112073058421111120890584780101*/                    
其实,统计信息中存放的就是一个关于某列的“统计”的信息,你看上面的输出,就是一个直方图,每个id值,会出现多少次,也就是有多少行信息,以利于优化器,做出正确的判断。

比如,id这列,假设,当你的语句是select * from tb_object where id = 3

而id = 3的记录,有100w条,而整个表的记录就500w条,那么sql server优化器知道后,可能就会采用表扫描的执行计划了。

相应的,如果id = 3的记录只有1000条,而表有100w条记录,那么sql server会考虑采用索引查找的方式,来获取数据。

--创建有主键的表,会自动建立聚集索引,自动生成索引所对应的统计信息create table txt(id numeric(10,0) primary key,                 v varchar(20),                 vv int )--建立非聚集索引后自动生成索引所对应的统计信息create index txt_v on txt(v)insert into txtselect object_id,       type_desc,       schema_idfrom sys.objectswhere LEN(type_desc) < 20--1.1创建统计信息,通过扫描表或索引视图中的所有行来计算统计信息create statistics txtStatson dbo.txt(v,vv)with fullscan--1.2采用为10%的行create statistics txtStatsPercenton dbo.txt(v,vv)with sample 10 percent  --1.3采样为100行create statistics txtStatsRowon dbo.txt(v,vv)where id < 1000         --使用筛选谓词创建的统计信息with sample 100 rows,      norecompute    --覆盖数据库选项选项AUTO_STATISTICS_UPDATE                    --查询优化器将完成statistics_name的任何正在进行中的统计信息更新                    --并禁用将来的更新--2.更新表或索引视图的统计信息--2.1更新表中为某些列建立的统计信息update statistics txt(txtStats)update statistics txt(txtStats)with sample 50 percentupdate statistics txt(txtStatsRow)with resample,    --使用最近的采样速率更新每个统计信息     norecompute  --查询优化器将完成此统计信息更新并禁用将来的更新--2.2更新索引的统计信息update statistics txt(txt_v)with fullscan        --2.3更新表的所有统计信息update statistics txtwith all   --2.4更新表中所有为某一些列建立的统计信息update statistics txt(txt_v)with columns--2.5更新表中所有为索引建立的统计信息update statistics txt(txt_v)with index/*==============================================调用CREATE STATISTICS语句以便对于不是统计信息对象中第一列的列创建单列统计信息。创建单列统计信息会增加直方图的数目,这可能会改进基数估计、查询计划和查询性能。统计信息对象的第一列具有直方图;其他列不具有直方图.在查询执行时间很重要并且不能等待查询优化器以生成单列统计信息时,sp_createstats对于基准确定之类的应用程序十分有用。在大多数情况下,无需使用sp_createstats,而是由查询优化器根据需要生成单列统计信息,以便在AUTO_CREATE_STATISTICS选项为ON时改进查询计划.========================================================*/--3.1参数值默认都是NO.--@indexonly:仅对位于现有索引中并且不是任何索引定义中的第一列的列创建统计信息--@fullscan: 将CREATE STATISTICS语句与FULLSCAN选项一起使用--@norecompute:将CREATE STATISTICS语句与NORECOMPUTE选项一起使用exec sp_createstats           @indexonly ='indexonly',@fullscan  ='fullscan',      @norecompute = 'norecompute'--3.2对当前数据库中所有用户定义表和内部表运行UPDATE STATISTICS--将使用默认的抽样来更新统计信息exec sp_updatestats @resample = 'no'--使用UPDATE STATISTICS语句的RESAMPLE选项来更新统计信息exec sp_updatestats @resample = 'resample'/*====================================================4.显示表或索引视图的当前查询优化统计信息查询优化器使用统计信息来估计查询结果中的基数或行数,查询优化器就可以创建高质量的查询计划。例如,查询优化器可以使用基数估计,在查询计划中选择索引查找运算符而不是索引扫描运算符,避免消耗大量资源的索引扫描,提高查询性能。对于表,统计信息是根据索引或表列的列表创建的。统计信息包含一个带有统计信息的相关元数据的标题、一个用于度量各列之间的相关性的密度向量、一个带有统计信息第一个键列中的值的分布的直方图。数据库引擎可以使用统计信息中的任何数据计算基数估计。DBCC SHOW_STATISTICS 根据统计信息对象中存储的数据显示标题、直方图和密度向量。使用以下语法,您可以指定表或索引视图以及target(目标索引名称、统计信息名称或列名)DBCC SHOW_STATISTICS ( table_or_indexed_view_name , target ) [ WITH [ NO_INFOMSGS ] < option > [ , n ] ]< option > :: =    STAT_HEADER | DENSITY_VECTOR | HISTOGRAM | STATS_STREAM======================================================*/DBCC SHOW_STATISTICS('dbo.txt','txtStats') DBCC SHOW_STATISTICS('dbo.txt','vv') with HISTOGRAM--5.删除某个表的统计信息drop statistics txt.txtStatsRow,                txt.txtStatsPercent  --表.统计信息名


统计信息的更新时间:

 

--1.更新日期,列名select stats_date(s.object_id,s.stats_id) 统计信息的最新更新的日期,       c.name as 列名,       *from sys.stats sinner join  sys.stats_columns sc        on s.object_id = sc.object_id and   s.stats_id = sc.stats_idinner join sys.columns c        on s.object_id = c.object_id and   sc.column_id = c.column_idwhere s.object_id  = object_id('xx')--2.或者直接这样sp_helpstats 'xx'


那么在更新某个表的统计信息时,会导致阻塞问题吗?

通过实验发现,在更新某个表的统计信息时,会对表加上X锁,这个肯定会导致阻塞问题:



4、查询调整

create table txt(id numeric(10,0) primary key,                 v varchar(20),                 vv int )create index txt_v on txt(v)insert into txtselect object_id,       type_desc,       schema_idfrom sys.objectswhere LEN(type_desc) < 20/*=================================================1.1动态sql语句很容易导致SQL注入,与存储过程不同的是,动态sql、常规即席查询在每次执行时都会生成新的执行计划,所以查询的性能不稳定.===================================================*/exec ('select * from txt');/*===============================================1.2创建可重复使用的、只有查询参数不同的查询计划,来处理动态sql的性能问题.参数是类型安全的,不能以非指定的数据类型使用,也就是参数类型与字段类型必须一致,否则会报错.=================================================*/exec sp_executesql @statement = N'select *                from txt                where id > @id and                     vv > @vv',                    @params    = N'@id numeric(10,0),                 @vv int',    --定义为@id int时会报错@id = 10000,@vv = 2--2.强制SQL Server使用特定的查询计划set statistics xml onselect * from txt where id > 1000 and  vv > 2set statistics xml offselect *from txtoption(use plan'<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.1" Build="10.50.1600.1"><BatchSequence><Batch><Statements><StmtSimple StatementText="SELECT * FROM [txt] WHERE [id]>@1 AND [vv]>@2" StatementId="1" StatementCompId="1" StatementType="SELECT" StatementSubTreeCost="0.00429444" StatementEstRows="42.2945" StatementOptmLevel="TRIVIAL" QueryHash="0xA4E0AA4B0A87F88B" QueryPlanHash="0x3325250D8A42F500"><StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false"/><QueryPlan DegreeOfParallelism="1" CachedPlanSize="16" CompileTime="1" CompileCPU="1" CompileMemory="136"><RelOp NodeId="0" PhysicalOp="Clustered Index Seek" LogicalOp="Clustered Index Seek" EstimateRows="42.2945" EstimateIO="0.00386574" EstimateCPU="0.0004287" AvgRowSize="34" EstimatedTotalSubtreeCost="0.00429444" TableCardinality="292" Parallel="0" EstimateRebinds="0" EstimateRewinds="0"><OutputList><ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="id"/><ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="v"/><ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="vv"/></OutputList><RunTimeInformation><RunTimeCountersPerThread Thread="0" ActualRows="5" ActualEndOfScans="1" ActualExecutions="1"/></RunTimeInformation><IndexScan Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" NoExpandHint="0"><DefinedValues><DefinedValue><ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="id"/></DefinedValue><DefinedValue><ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="v"/></DefinedValue><DefinedValue><ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="vv"/></DefinedValue></DefinedValues><Object Database="[test2]" Schema="[dbo]" Table="[txt]" Index="[PK__txt__3213E83F4D1564AE]" IndexKind="Clustered"/><SeekPredicates><SeekPredicateNew><SeekKeys><StartRange ScanType="GT"><RangeColumns><ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="id"/></RangeColumns><RangeExpressions><ScalarOperator ScalarString="CONVERT_IMPLICIT(numeric(10,0),[@1],0)"><Identifier><ColumnReference Column="ConstExpr1003"><ScalarOperator><Convert DataType="numeric" Precision="10" Scale="0" Style="0" Implicit="1"><ScalarOperator><Identifier><ColumnReference Column="@1"/></Identifier></ScalarOperator></Convert></ScalarOperator></ColumnReference></Identifier></ScalarOperator></RangeExpressions></StartRange></SeekKeys></SeekPredicateNew></SeekPredicates><Predicate><ScalarOperator ScalarString="[test2].[dbo].[txt].[vv]>CONVERT_IMPLICIT(int,[@2],0)"><Compare CompareOp="GT"><ScalarOperator><Identifier><ColumnReference Database="[test2]" Schema="[dbo]" Table="[txt]" Column="vv"/></Identifier></ScalarOperator><ScalarOperator><Identifier><ColumnReference Column="ConstExpr1004"><ScalarOperator><Convert DataType="int" Style="0" Implicit="1"><ScalarOperator><Identifier><ColumnReference Column="@2"/></Identifier></ScalarOperator></Convert></ScalarOperator></ColumnReference></Identifier></ScalarOperator></Compare></ScalarOperator></Predicate></IndexScan></RelOp><ParameterList><ColumnReference Column="@2" ParameterCompiledValue="(2)" ParameterRuntimeValue="(2)"/><ColumnReference Column="@1" ParameterCompiledValue="(1000)" ParameterRuntimeValue="(1000)"/></ParameterList></QueryPlan></StmtSimple></Statements></Batch></BatchSequence></ShowPlanXML>')--3.不修改应用程序,应用查询提示exec sp_create_plan_guide@name = 'plan_guide_txt',@stmt = 'select *          from txt          inner join sys.objects o         on o.object_id = txt.id',@type = 'sql',@module_or_batch = null,@params = null,@hints  = 'option(merge join)'--当下面的这段代码与上面的代码完全一样(包括空格,回车)时,系统才会应用查询提示select *          from txt          inner join sys.objects o         on o.object_id = txt.id         --4.从缓存创建计划指南beginselect * from txt inner join sys.objects oon o.object_id = txt.idselect * from sys.objectsendgo--找到计划句柄select e.text,       d.statement_start_offset,       d.plan_handle   --计划句柄       from sys.dm_exec_query_stats dcross apply sys.dm_exec_sql_text(d.sql_handle)ewhere e.text like '%from txt%' /*========================================================从计划句柄建立计划指南参数@statement_start_offset:在批处理中可能会有多条语句,此参数指出批处理中创建计划指南的语句,在批处理中的开始偏移。如果指定为NULL,那么会为批处理中的所有语句建立计划指南==========================================================*/exec sp_create_plan_guide_from_handle@name = 'plan_guide_txt_handle',@plan_handle = 0x060018007BA32F074021425A020000000000000000000000,@statement_start_offset = 14  --5.使用计划指南把非参数化查询参数化--5.1运行多条类似的查询select * from txt where id = 8select * from txt where id = 9--5.2通过查询缓存的计划所对应的sql文本,发现很多都是相同的--而且大部分的objtype都是proc,adhoc,prepared.SELECT * FROM SYS.dm_exec_cached_plans ECROSS APPLY SYS.dm_exec_sql_text(E.plan_handle)EEWHERE EE.text LIKE '%select * from txt where id =%'declare @sqltext nvarchar(max)declare @parameter nvarchar(max)--5.3获取查询的参数化形式以及查询的参数,放入变量中exec sp_get_query_template @querytext = N'select * from txt where id = 8',@templatetext= @sqltext output,@parameters = @parameter output--5.4使用模板来创建计划指南exec sp_create_plan_guide@name = 'plan_guide_txt_template',@stmt = @sqltext,@type = 'template',  @module_or_batch = null,@params = @parameter,@hints = 'option(parameterization forced)' --5.5再次查询发现多条执行计划已经变为一条,usecounts计数增加SELECT * FROM SYS.dm_exec_cached_plans ECROSS APPLY SYS.dm_exec_sql_text(E.plan_handle)EEWHERE EE.text LIKE '%select * from txt where id =%'--6.显示计划指南的元数据select p.plan_guide_id,       p.name,       p.create_date,       p.modify_date,              p.is_disabled,  --是否禁用计划指南       p.query_text,   --创建计划指南所依据的查询文本              p.scope_type,       --3个类型:object,sql,template       p.scope_type_desc,              p.scope_object_id , --如果类型为object,那么指出对象id              scope_batch,        --如果scope_type为SQL,则为批处理文本。                           --如果批处理类型不是SQL,则其值为NULL       p.parameters,       --定义与计划指南关联的参数列表的字符串              p.hints             --与计划指南关联的 OPTION 子句提示       from sys.plan_guides p/*=============================================================7.验证指定计划指南的有效性。返回计划指南应用于其查询时遇到的第一条错误消息。如果计划指南有效,则将返回一个空的行集。在更改数据库的物理设计后,计划指南可能会变为无效。例如,如果计划指南指定了特定索引并且随后将该索引删除,则查询将不能再使用该计划指南。通过验证计划指南,可确定优化器是否能够在不进行修改的情况下直接使用该指南。例如,基于函数的结果,可决定删除该计划指南并重新调整查询或修改数据库设计,例如,重新创建计划指南中指定的索引。===============================================================*/select pp.msgnum,     --错误消息的 ID       pp.severity,   --消息的严重级别       pp.state,      --错误的状态号,用于指示发生错误的代码位置       pp.message     --错误的消息正文from sys.plan_guides pcross apply sys.fn_validate_plan_guide(p.plan_guide_id) pp/*==============================================8.删除或者禁用计划指南disable,disable all:禁用(所有)计划指南  enable,enable all:启用(所有)计划指南      drop,drop all:删除(所有)计划指南      注意:当指定all时,不能指定计划指南名称。================================================*/exec sp_control_plan_guide@operation = 'disable',    --禁用计划指南@name = 'plan_guide_txt'--删除所有计划指南exec sp_control_plan_guide@operation = 'drop all'

 

5、资源调控

 在SQL Server 2008中引入了使用资源调控器来限制工作负荷的资源消耗。在SQL Server内部包含了两个资源池:默认和内部。内部资源池不能修改,并且使SQL Server的活动不受资源的限制。默认资源池可以把连接请求,连接、配置资源调控器,默认情况下没有限制,之后可以修改。

 

一个或多个工作组可以绑定到一个资源池,使用工作负荷组可以定义资源池中重要的请求、最大授予内存比、最大以秒为单位的cpu时间、最大授予内存超时时间、最大并行度、同时执行的请求的最大数量。工作负荷组也包含:内部和默认工作组。默认工作组用在没有被任何分类器用户定义函数覆盖的任何请求上。多个工作负荷组可以关联到一个资源池,但是一个工作负荷组不能关联到多个资源池。

在创建用户定义工作负荷组和绑定到资源池后,可以创建一个帮助确定:进入的SQL Server连接和请求属于哪个工作负荷组的分类器用户定义函数。

 

--1.创建资源池--创建应用程序资源池create resource pool app_querywith(MIN_CPU_PERCENT = 25,MAX_CPU_PERCENT = 75,MIN_MEMORY_PERCENT = 25,MAX_MEMORY_PERCENT = 75)--创建即席查询资源池CREATE RESOURCE POOL adhoc_querywith(min_cpu_percent = 5,max_cpu_percent = 25,min_memory_percent = 5,max_memory_percent = 25)--修改即席查询资源池alter resource pool adhoc_querywith(min_memory_percent = 10,max_memory_percent = 50)--2.创建工作负荷组--创建应用程序a的工作负荷组create workload group app_awith(importance = high,request_max_memory_grant_percent = 75,request_max_cpu_time_sec = 75,request_memory_grant_timeout_sec = 120,max_dop = 8,group_max_requests = 8)using app_query   --使用应用程序资源池--创建应用程序b的工作负荷组create workload group app_bwith(importance = low,request_max_memory_grant_percent = 50,request_max_cpu_time_sec = 50,request_memory_grant_timeout_sec = 360,max_dop = 1,group_max_requests = 4)using app_query   --使用应用程序资源池--创建即席查询工作负荷组create workload group adhoc_userwith(importance = low,request_max_memory_grant_percent = 100,request_max_cpu_time_sec = 120,request_memory_grant_timeout_sec = 360,max_dop = 1,group_max_requests = 5)using adhoc_query--修改工作负荷组alter workload group app_bwith (importance = medium)--3.分类器函数必须在master数据库中创建use mastergo--返回工作负荷组名称,系统会根据工作组名称,将连接定位到工作组所对应的资源池create function dbo.wc_classifier()returns sysnamewith schemabindingasbegindeclare @resource_group_name sysnameif SUSER_SNAME() in ('sa')set @resource_group_name = 'app_a'if SUSER_SNAME() in ('sa')set @resource_group_name = 'app_b'if HOST_NAME() in ('abc')set @resource_group_name = 'adhoc_query'if @resource_group_name is nullset @resource_group_name = 'default'return @resource_group_nameendgo--设置资源调度器的分类器函数,并且重新配置alter resource governorwith(classifier_function = dbo.wc_classifier)go--为了启用配置,需要执行reconfigurealter resource governor reconfigurego--4.查看元数据--资源池的元数据select pool_id,       min_cpu_percent,       max_cpu_percent,              min_memory_percent,       max_memory_percentfrom sys.resource_governor_resource_pools--负荷工作组元数据select group_id,   name,      pool_id,      importance,      request_max_memory_grant_percent,   request_max_cpu_time_sec,   request_memory_grant_timeout_sec,      max_dop,   group_max_requests          from sys.resource_governor_workload_groups--显示资源调控器的配置信息,包含了:分类器函数,是否启用select classifier_function_id,       OBJECT_NAME(classifier_function_id,                   DB_ID('master')                  ),         --函数名       is_enabled            --是否启用from sys.resource_governor_configuration--5.删除资源池,工作负荷组,分类器函数use mastergodrop workload group app_adrop workload group app_bdrop workload group adhoc_userdrop resource pool adhoc_querydrop resource pool app_query--禁用设置alter resource governor disable--设置不在使用分类器函数alter resource governor with(classifier_function = null)--删除分类器函数drop function dbo.wc_classifier


 

 

原创粉丝点击