SQL Server才会对其创建执行计划
ANSI_PADDING是针对表上的每个列单独存储(数据范例为varchar/nvarchar/varbinary)。
常见的事件有:SQL Server 的缓冲池(buffer cache)已满,SQL Server知道这个存储进程会传入2000-01-01这个值,好比挪用第二个存储进程:EXEC List_orders_2 19900101 执行打算依旧利用OrderDate上的索引,SQL Server重启,SQL Server没有义务建设一个对所有值都是最佳的执行打算,所以预估1行会越发公道。
可以显示出差异挪用时的配置,并利用一个常量替换变量和参数。
嗅探当前参数值,只有1行,假如是这样就太不智慧了,除了这个之外尚有两个选项:LANGUAGE和DATEFIRST,双引号被认为和中括号([])一样,因为这里利用了一个叫推迟定名理会(deferred named resolution)的成果),可是SQL Server也会编译存储进程, c FROM mytablefunc(9)它们跟直接利用即席查询(ad-hoc queries)会见基本表没有什么区别。
因此,所以这里照旧保存原有称号,对付每个语句, 为了制止对后续的影响,当设为ON时。
因为这次查找的是靠近1/3的订单数据, 作为提醒,所以发起设为OFF,对付返回表的大部门甚至全部行而言,在SQL 2005及其后续版本中,是按830行预估行数举办。
甚至可以利用短路模式不会见底层表,那么对付SQL Server来说, 2,这种写法与嵌套存储进程没有区别,我(作者)曾经经验过一次在系统中一个要害存储进程溘然建变慢,以便下一次用户执行它的时候,因为我但愿以简捷的方法演示,在出产情况中利用SELECT *并不是什么好的习惯,通过这个信息获得关于执行这个语句的最佳预估方法,这里的要害点是:存储进程中的两个语句。
前面提到过什么时候会触发语句级此外重编译。
会发明第一个返回很大都据,假如不传参数。
假如把鼠标移到查找和扫描两个操纵符上,可是会触发存储进程内部某些语句的重编译, 谜底是SQL Server针对第二个存储进程的执行建设了第二个缓存条目,让东西运行在QUOTED_IDENTIFIER ON下,尽量如此, ... 需要知道的是,对付第二个存储进程。
小结:在本文中,常见的有:语句中涉及的表界说被修改。
这个cache key是一个实际运行时的配置,表变量的预估行数为1,可是实际上并不是所有系统都这样,在对应表中的数据漫衍环境, 直到执行存储进程时,也就是等价于EXEC List_orders_4。
提醒:SQL Server 2000中没有语句级此外重编译,可是由于存储进程的极其遍及的利用,你可以通过在SSMS的执行界面中加上SET ARITHABORT OFF呼吁来验证这个问题,这个存储进程是特制的,可是对付有大量用于在短时间内执行大量存储进程的OLTP系统, 下一节接头:不老是参数嗅探的错 ,这个打算会驻留在缓存中,所以SQL Server会凭据高出1行的预估数量来编译优化。
表扫描/聚积索引扫描会越发高效,所以参数嗅探才会变得如此的重要. 差异配置的查询打算:在缓存中,而第二个没有数据.查抄执行打算可以发明也完全差异.第一个执行利用了聚积索引扫描(对付返回大量数据来说是最佳方法),所以它假设没有任意值返回,凡是SQL Server对表变量的预估永远是1行。
针对这种环境,可是有一个很雷同的写法:CREATE PROCEDURE Some_sp ASDECLARE @sql nvarchar(MAX)。
可是这回在利用SSMS毗连SQL Server时改变ARITHABORT的默认配置, 对此我的发起是尽大概制止在SQL Server中存在独立于语言和日期配置,为什么会产生这种环境呢?为了大白优化器的抉择。
可是并不知道后续操纵,即可知道预估行数, b,对特定查询。
然后直接执行, @fromdate)SELECT *FROM OrdersWHERE OrderDate @fromdateIF @ix = 1CREATE INDEX test ON Orders (ShipVia)SELECT *FROM OrdersWHERE OrderDate @fromdateGOEXEC List_orders_7 19980101,这也是为什么你的语句在应用措施中慢可是在SSMS中能运行精采的原因之一,SQL Server因此抉择利用索引查找,参数是可选的,发起在SQL Agent功课的第一步总带上SET QUOTED_IDENTIFIER ON,可是最常见的关于在应用措施中很慢,在下一次执行时,老是利用统一的日期名目,可是全局来说是答允所有已毗连的用户利用,这种计策叫做参数嗅探(parameter sniffing),对付第三个存储进程,部门值的明细如下: 利用ADO.NET/ODBC/OLE DB的应用措施 SSMS/查询阐明器 SQLCMD/OSQL/BCP/SQL Agent ISQL/DB-Library ANSI_NULL_DFLT_ON ON ON ON OFF ANSI_NULLS ON ON ON OFF ANSI_PADDING ON ON ON OFF ANSI_WARNING ON ON ON OFF CONCATE_NULLS_YIELD_NULL ON ON ON OFF QUOTED_IDENTIFIER ON ON OFF OFF ARITHABORT OFF ON OFF OFF 上面可以看到,假如你的应用措施完全没有用到存储进程,直到某些事件导致打算被移出缓存,也就是说,因为这次触发了重编译,可是利用差异的参数:EXEC List_orders_7 19960101,能跳过编译阶段,可是利用SSMS毗连,这里较量需要留意的是sql_handle和plan_handle列。
正如前面说的,应该老是带上-I选项, @par1,可是关于动态SQL的编译会在后头章节先容,因为缓冲池是存储在内存中,越发公道的方法已变动是改写成下面第五个存储进程的样子:USE NorthwindGOCREATE PROCEDURE List_orders_5 @fromdate DATETIME = NULLASDECLARE @fromdate_copy DATETIMESELECT @fromdate_copy = coalesce(@fromdate,所以SQL Server会对当前参数值建设查询打算。
利用索引查找+键值查找。
而SQL Server预估要返回249行,留意存储进程的打算缓存并不绑定到特定会话或用户,假如这时候的参数值和之前的差异,而且不会阐明后续步调,这里挑出差异的展示,你很大概因为QUOTED_IDENTIFER的差异默认值导致差异的执行打算,也和第一个存储进程一样,更精确地说是一个参数,就是表变量。
在SSMS中很快的原因是参数嗅探和差异的ARITHABORT默认值,SQL Server不建设查询打算,下面是例子:USE NorthwindGOCREATE TYPE temptype AS TABLE (a INT NOT NULL PRIMARY KEY)GOCREATE PROCEDURE List_orders_10 @ids temptype READONLYASSELECT COUNT(*)FROM Orders OWHERE EXISTS (SELECT *FROM @ids iWHERE O.OrderID = i.a)GODECLARE @ids temptypeINSERT @ids (a)SELECT OrderIDFROM OrdersEXEC List_orders_10 @idsGODROP PROCEDURE List_orders_10DROP TYPE temptype 查询打算和List_orders_9的第二个SELECT一样,所以应用措施和SSMS执行的同一个存储进程也利用差异的缓存条目,SQL Server都要编译(也就是优化和发生查询打算),SQL Server才会对其建设执行打算,这些纵然每次都编译,假如每个用户的默认语言差异,输入值被复制到一个当地变量,然后回到之前的主题,数据页中的每一行城市触发一次会见。
对付当地变量,所以利用尺度假设,可是假如你在SQL Agent要实现松散的批处理惩罚语句,这个缓存池凡是包括了数据和查询打算,而第三个存储进程利用的是聚积索引扫描操纵,并利用包括实际执行打算(或Ctrl+M再执行),也就是说假如你按下面方法运行:SET ANSI_NULLS,那么意味着你实际上有两个进程,有一个变种情景,你大概实际上获得了一个差异的查询,也就是动态SQL的接头,好比。
因为在应用措施和SSMS中,利用sp_configure或SSMS修改了某些影响查询打算的设置参数,第一个语句因为新加的索引导致了重编译, 接上文:领略机能的机密应用措施中慢, 一旦上面提到的事件被触发。
强烈 发起不要修改 当利用SQLCMD和OSQL毗连时,就有所差异了, 可是也有一些时间不会影响整个存储进程的打算缓存,SQL Server预估只会返回1行数据。
--------------------------------------------------------------------------------------------------------------------------- 接下来按下面方法执行存储进程,@ix BITASSELECT @fromdate = dateadd(YEAR,但照旧有一些发起可用:记得上面表格中的前六个是仅仅为了向后兼容,默认就是null,这一点在后续小节先容,在实践中,语句涉及的表的统计信息更新或新建统计信息,假设@fromdate值为NULL,在这个例子内里,语句中涉及的表上的索引改观,如下面的第四个存储进程:USE NorthwindGOCREATE PROCEDURE List_orders_4 @fromdate DATETIME = NULLASIF @fromdate IS NULLSELECT @fromdate = 19900101SELECT *FROM OrdersWHERE OrderDate @fromdate 在这个存储进程中,那么ARITHABORT是OFF的,并编译出一个更佳的查询打算,最后就是某些影响缓存键的SET设置是汗青遗留设置,SQL Server缓存存储进程的查询打算,因为此时SQL Server只需要会见一次表数据,很大概没有ARITHABORT ON 的打算在打算缓存中,SQL Server需要把过期的内容排除出去,固然此时不是最佳的查询打算,可是此刻第二个语句不再重编译了,新的查询打算就会被编译、优化然后建设,可是它能很好地演示产生了什么:USE NorthwindGOCREATE PROCEDURE List_orders_7 @fromdate DATETIME, 什么是存储进程? 固然这个问题有点愚蠢。
假如两个毗连利用了差异的SET选项,那么它会结构一个只有常量的扫描操纵而完全不需要会见表(可以利用SELECT * FROM Orders WHERE OrderDate NULL 来检讨),确实如此, 语句重编译的结果:为了完整地相识SQL Server如何发生查询打算。
可是SQL Server不知道@fromdate的值在下一个查询时会改变,因为SQL Server嗅探到值为1998-01-01而且预估查询会返回267行数据,那么此刻差不多可以答复一开始的问题了,预估返回249行,你的存储进程大概对差异的表利用沟通的参数,在得知预估行数只有1行时。
cache key中很是重要的值是set_options,假如@fromdate在运行进程中依旧是这个值的话。
所以它以为扫描是最佳选择,最重要的SET选项是ARITHABORT。
一个存储进程有一个查询打算是不是意味着所有人都可以用它?其实不是,执行了ALTER PROC/PROCEDURE呼吁,在Northwind数据库中的Orders表。
所以SQL Server不能确定查询是否有数据返回,可以看到下面两个功效: 查询1 查询2 查询3 个中值得存眷的是预估影响行数(Estimated Number of Rows),重启会清空内存。
SQL Server会从统计信息中查找针对这个查询,而第二个执行利用了索引查找+键值查找(对付没数据返回时是最佳方法), @params,假如存储进程有多个语句,开销就会增加。
SQL Server对此一无所知,所以利用一个尺度假设,你就大概是碰到了参数嗅探的环境,所有SELECT语句都利用了聚积索引扫描,所以可以通过它去筛选掉其他 缓存中不相干的条目,大概由于嗅探差异的参数值而编译得出差异的查询打算, 并且极有大概你此刻在应用措施中执行的慢查询在SSMS中也一样很慢,会因为所有CPU资源被耗尽而带来庞大危机,这一次, SQL Server如何生成查询打算:概述:当你输入以CREATE PROCEDURE(可能CREATE FUNCTION、CREATE TRIGGER同理)的存储进程时,可是当重编译产生时,后续章节会做越发深入的探讨,SQL Server并不知道@fromdate值的改变,SQL Server并不建设任何查询打算,该选项的默认值是差异的,SSMS中快(1)简介 本文先容SQL Server如何编译存储进程并利用打算缓存,有830行数据,并利用归并联接操纵符与表变量关联,而查找加键值查找,所以第一个查询实际上是利用了1998-01-12而第二个查询实际上利用了1998-12-01,那么对付后续的执行来说,假如SQL Server把这值作为最后的输入,它们雷同表变量的方法处理惩罚。
可是最起码你不会因为在SSMS中获得差异的机能而感想狐疑,尽量返回所有订单数据,多步表值函数,如上图查询3所示,最终呈现差异的机能差别。
下面结构一个特制的存储进程:USE NorthwindGOCREATE PROCEDURE List_orders_6ASSELECT *FROM OrdersWHERE OrderDate 12/01/1998GOSET DATEFORMAT dmyGOEXEC List_orders_6GOSET DATEFORMAT mdyGOEXEC List_orders_6GO按上面方法,聚积索引的叶节点存储了数据自己。
并不老是在运行时才会利用。
会看到这次利用了聚积索引扫描操纵。
别的也演示了在缓存中的同一个存储进程可以有多个条目,当存储进程被编译一次之后,以便后续被重用,可是在这个阶段,在编译这些查询时,优化器按照输入值计较出对应的预估行数,SQL Server从头嗅探当前参数值,Order表上利用了聚积索引扫描, QUOTED_IDENTIFIER ONgoEXEC stupid NULL功效将是: @x is NULL 当QUOTED_IDENTIFIER为OFF时,利用了索引查找操纵,触发器 这里利用一个越发通用和严谨的技能术语模组(modules)来标识, 要害点:在本节中,而且由处事器范畴的设置来节制新用户的默认语言。
可是SQL Server又不得不生成一个满意不管@fromdate在运行时传入什么值都能返回正确功效的执行打算,可以看到除了实际影响行数(actual number of rows)之外其他都和第二个存储进程一样,则在cache keys中大概获得差异的查询打算,设为OFF很少会有问题,在大型的数据客栈内里,可是也可以在由差异的用户利用差异的日期名目并行提交,执行了DBCC FREEPROCCACHE呼吁,对付ARITHABORT,每个语句都被独自优化,可是凡是而言,此时SQL Server举办了全表扫描(留意,反而有长处, epa.value) + FROM sys.dm_exec_plan_attributes(qs.plan_handle) epaWHERE epa.is_cache_key = 1ORDER BY epa.attributeFOR XML PATH()) AS a(attrlist)WHERE est.objectid = object_id (dbo.List_orders_6) AND est.dbid= db_id(Northwind) 内里的DMV sys.dm_exec_query_stats别离针对当前每个查询记录一个打算缓存条目。
那么本文大部门内容也是有效的,别的一方面。
执行了对存储进程的sp_recompile呼吁,好比:SELECT abc,在第二次执行中,1实际执行打算如下: 查察实际执行打算可以看到第一个SELECT语句利用了聚积索引扫描, 个中一个转换SET_OPTIONS成可识此外值的方法是:SELECT convert(binary(4)。
可以利用下面查询查察:SELECT qs.plan_handle,包括利用ALTER INDEX或DBCC DBREINDEX重建索引,@params nvarchar(MAX)SELECT @sql = SELECT ......EXEC sp_executesql @sql,可是这个语句中查询查询打算的属性(cache keys)。
def FROM myviewSELECT a,执行是一个接一个地举办,利用了嵌套轮回联接关联Order表的聚积索引查找和表变量的聚积索引,ANSI_NULLS和QUOTED_IDENTIFIER配置城市记录在工具中,双引号()被认为和单引号()等价,假如雷同下面写法。
SQL Server并不知道运行时的详细值, 19900101)SELECT *FROM OrdersWHERE OrderDate @fromdate_copy假如你执行这个存储进程, 上面罗列的并不是完整的列表,编译依旧会通过,ANSI_WARNING是否为ON也差池其有任何影响,不幸的是,我们可以把思维扩展到当地变量中:USE NorthwindGOCREATE PROCEDURE List_orders_8ASDECLARE @fromdate DATETIMESELECT @fromdate = 20000101SELECT *FROM OrdersWHERE OrderDate @fromdateCREATE INDEX test ON Orders (ShipVia)SELECT *FROM OrdersWHERE OrderDate @fromdateDROP INDEX testON OrdersGOEXEC List_orders_8GODROP PROCEDURE List_orders_8 执行打算如下: 在这个例子中,可以通过配置来修改,重编译就会触发,对付这类语句。
而且不能让你的应用跑得更快,而别的一个查询就不会,可是它有一个关于本身的查询打算缓和存条目(cache entry),然后获得大概和应用挪用的存储进程差异的查询打算,用于说明为什么查询打算会差异:差异的日期名目导致了差异的功效,预估数据的出处?前面说了为什么会呈现差异的执行打算:因为预估数量的差异,830行的30%就是249行。
内里大部门配置由SET呼吁节制。
可是对付相对较大局限的返回功效而言,NULL代表着未知。
可是这次利用扫描操纵是公道的。
假如你用应用措施毗连SQL Server,应用措施利用了打算因为参数的实际值差异而被嗅探成差异的查询打算,这就衍生出一个很重要的 特性:优化器对运行时传入的变量绝不知晓,下面看一小我私家为特制的存储进程,你大概会好奇从SQL 2008引入的表值参数。
查询大概返回任意数据,这些统计信息大概被SQL Server自动建设和更新。
去掉不须要的信息之后,在第二个SELECT中。
可是对付第三个存储进程,预估就纷歧样了:USE NorthwindGOCREATE PROCEDURE List_orders_9ASDECLARE @ids TABLE (a INT NOT NULL PRIMARY KEY)INSERT @ids (a)SELECT OrderIDFROM OrdersSELECT COUNT(*)FROM Orders OWHERE EXISTS (SELECT *FROM @ids iWHERE O.OrderID = i.a)CREATE INDEX test ON Orders (ShipVia)SELECT COUNT(*)FROM Orders OWHERE EXISTS (SELECT *FROM @ids iWHERE O.OrderID = i.a)DROP INDEX testON OrdersGOEXEC List_orders_9GODROP PROCEDURE List_orders_9 执行打算及预估行数如下: 表变量重编译之前的预估行数 表变量重编译之后的预估行数 在第一个SELECT中,当优化器举办优化时。
从头执行存储进程。
可是在SQL Server发生执行打算时,所以它也不确定后续是否真的会用这个参数值。
从而导致差异的执行打算。
这个差别导致了优化器选择差异的执行打算,又好比下面的挪用方法:USE NorthwindGOEXEC sp_recompile List_orders_2GOSET DATEFORMAT dmyGOEXEC List_orders_2 12/01/1998GOSET DATEFORMAT mdyGOEXEC List_orders_2 12/01/1998GO 第一句sp_recompile是为了刷掉旧的打算缓存确保对演示没有影响,可是对付SQL Agent而言就稍微贫苦一点,查询利用了一个变量,打开实际执行打算并运行。
在SSMS中, a.attrlistFROM sys.dm_exec_query_stats qsCROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) estCROSS APPLY (SELECT epa.attribute + = + convert(nvarchar(127)。
那么产生了什么事?是不是因为SET DATEFORMAT触发了重编译?不是,这个存储进程是工钱的。
除了上面罗列的四类工具之外。
当你建设一个存储进程、视图、表等等时, 4347) 默认配置:SQL Server的默认值具有必然的汗青遗留问题,日期是常量。
本节先容关于缓存中同一个存储进程也大概有多个查询打算.为了演示需要,可是不是全部都这样,可是由于日期名目纷歧样,参数和变量:此刻看看在Northwind库中的这三个存储进程: USE NorthwindGOCREATE PROCEDURE List_orders_1ASSELECT *FROM OrdersWHERE OrderDate 20000101GOCREATE PROCEDURE List_orders_2 @fromdate DATETIMEASSELECT *FROM OrdersWHERE OrderDate @fromdateGOCREATE PROCEDURE List_orders_3 @fromdate DATETIMEASDECLARE @fromdate_copy DATETIMESELECT @fromdate_copy = @fromdateSELECT *FROM OrdersWHERE OrderDate @fromdate_copyGO--------------------------------------------------------------------------------------------------------------------------- 留意,第一次执行时的值很是不典范,利用索引查找+键值查找会过高开销,也大概被DBA操纵,以触发这个表的重编译,利用归并联接+Orders表的聚积索引扫描,因为在干系数据库中,(可是依旧是返回1行,这种方法适合于利用EXEC()执行的动态SQL可能利用sp_executesql执行的动态SQL语句,出格是对视图和内联表值函数(inline-table functions)。
DBA们会对个中一个表建设一个新索引,一般做法是查抄影响的预估行数,可是也有破例,对付参数。
我们看到了SQL Server如何编译一个存储进程和实际参数值对编译的影响,从图中可以看到表变量的预估行数酿成了830行,发生的SQL字符串不属于Some_sp,优化器是可以知道的,可是其时没有做深入研究,默认语言是基于每个用户设置的,对付第一个存储进程。
属性内里许多信息是沟通的。
时至今天一些默认值照旧依赖于客户端的毗连方法。
SQL Server嗅探出表变量上面的基数,那么会每个语句对应一行。
索引聚积索引扫描和表扫描是一样的),SQL Server会把视图/函数展开成实际语句,假如它从约束中揣度出不会返回任何数据。
这个问题就变得很现实了,也不呈此刻Some_sp执行打算中的任何部门,提到了以下一些要害内容:当一个查询包括一个常量时,从而使优化器从头优化第二个语句,SQL Server并不建设查询打算。
而由于第二个语句在执行之前呈现了CREATE INDEX语句,此时SQL Server底层更愿意利用直接扫描一次全表来低落开销,语句及功效如下: EXEC List_orders_1EXEC List_orders_2 20000101EXEC List_orders_3 20000101 前两个存储进程的执行打算如上图查询2所示。
而当你在SSMS中运行语句是,多个差异缓存键会导致同一个存储进程存在差异查询打算的潜在风险。
(这个假设依赖于语句的操纵符和从独一索引中推导出来的信息) 从中我们得出一个结论:假如你从一个存储进程中提取一个查询。
同时可以看到在查询被编译时,问题不大,因为这个并不适合所有系统。
0 实际执行打算和第一次执行一样,对付前两个存储进程。
在编译这个存储进程时,索引查找+键值查找(Key Lookup)是很好的计策,即返回所有订单数,SQL Server会先判定代码语法是否正确,今朝为止还没有找到对应的修改,切合通例,这里只是为了演示起见,这个进程成为优化(optimisation),可是实际的问题是:什么工具有本身的查询打算?SQL Server为下面四类工具建设查询打算:存储进程,尽量返回所有的订单数据.这个现象表白一个很重要的事实:存储进程首次执行时的参数值对后续的执行有很是大的影响.假如因为某些原因,外层挪用内层:CREATE PROCECURE Outer_sp AS...EXEC Inner_sp... 我猜大部门人会以为Inner_sp和Outer_sp是独立的,可是这又仅仅引出了下一个问题:为什么会差异呢?这也是本系列的要害点之一,sql_handle用于确定缓存条目中是关于谁人存储进程的,触发了第二个语句的重编译,而是直接利用SQL语句提交请求,标量用户自界说函数,并基于这些实际语句举办优化,那么查询打算也大概和之前的差异(意味着机能会有差别甚至庞大差别), 在某些环境下它就雷同于参数嗅探。
所以假如你仅在SQL Agent中运行存储进程。
这种环境下就算存储进程已经开始执行也大概触发,只需要把对应的SET呼吁写入存储进程中即可,标识一系列SET选项是否开启。
把查询打算放入缓存: 假如每一次存储进程被执行时,凡是会有几百个巨大查询的、大概需要分钟级别才气运行完的查询在执行,在现实情况中,仅仅是挪用它罢了,这是一个位掩码。
可是是在作为参数时已被处理惩罚而不是在存储进程中被处理惩罚,缓存的查询打算大概并不公道,不该该窜改。
所以它认为只返回1行数据,它的执行打算和第一、第二个存储进程一样,只有整个存储进程的重编译,可是它依旧利用上次执行的索引查找作为执行打算。
对付SET选项,这个存储进程在天天运行中都是一个接一个地运行。
可是应该留意到个中一个没提到的点:同一个存储进程差异参数的环境.也就是说。
Outer_sp的执行打算并不包括Inner_sp, 这些选项和差异的默认值确实让人狐疑。
我们需要清空演示时的结果:USE NorthwindGODROP INDEX testON OrdersDROP PROCEDURE List_orders_7 正如一开始说的,而是仅存储查询文本在数据库中,通过查询Orders表的统计信息。
在我本机的功效如下:plan_handleattrlist------------------------------------------------------------------------------------------- --------------------------------------------------0x05000D009D13BF5E30DF8F550300000001000000000000000000000000000000000000000000000000000000 compat_level=120 date_first=7 date_format=2 0x05000D009D13BF5ED0678F590300000001000000000000000000000000000000000000000000000000000000 compat_level=120 date_first=7 date_format=1 详细的说明可以查阅联机丛书:https://msdn.microsoft.com/zh-cn/library/ms189472.aspx ,查询适合利用索引查找+键值查找操纵, 基于这个原因,固然不是强制。
对付一个表返回少量数据而言,通过查抄发明语句中的表变量预估行数为41。
可是会在编译进程中嗅探输入值,可是对付存储进程传入的参数,同时也会查抄是否利用了不存在的列(可是假如你利用了不存在的表。
在实际应用中。
别的,假如产生这种环境,下面几个ANSI页的选项应该如下图所示,当呈现语句重编译时,SQL Server从头嗅探参数的输入,我们也知道了SQL Server把查询打算放入缓存,所以答允利用聚积索引扫描,可是统计信息究竟是表的取样数据,它真不知道这个值最终会是怎么样子的,假如你查察索引查找操纵符的属性,同时可以利用plan_handle去查找查询打算, 前面看到了SET DATEFORMAT带来的影响,SQL Server会完全信任这个常量,却是ON,可是在下一节我会接头办理方案,参数值是一样的, 说到表变量,语句涉及的表被执行了sp_recompile,也就是假设会有30%的掷中率,意味着SQL Server只需要思量这个值的环境,我们必需研究独立的语句在重编译时是奈何的,你大概还不知道怎么处理惩罚这种机能问题, QUOTED_IDENTIFIER OFFgoCREATE PROCEDURE stupid @x int ASIF @x = NULL PRINT @x is NULLgoSET ANSI_NULLS,在下一次执行存储进程的时候,因为SQL Server永远不会利用0行作为预估行数)这是一个关于参数嗅探的反结果的例子, 关于存储进程的布局,固然第二个SELECT因为@fromdate的不行知而产生了重编译,这里重点存眷让人头痛的存储进程问题,也不会带来什么危险,相对的BCP参数为-q,那么同一个存储进程就会利用差异的缓存条目, 当看到这里,。
相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://v30.fanwenzhu.com/sql/mssql/12791.shtml
相关文章
热门TAG
win10 ecshop 主机 阿里云 解决 配置 C# C++ 解析 SQL语句 命令 Go语言 方法 CSS3 HTML5 CSS win7 MSSQL 服务器配置 IIS7.5 IIS7 IIS6 IIS CentOS 7 Linux oracle数据库 oracle phpcms discuz discuz教程最新文章
-
SQL基本教程之行转列Pivo
时间:2021-01-20
-
region from hr.Employees union
时间:2021-01-20
-
有时候需要调整用户权限
时间:2021-01-19
-
(但使用 ORDER BY 子句并不
时间:2021-01-19
-
RAND()*10000)insert into Detail
时间:2021-01-19
-
OR 运算符:在两侧的查询
时间:2021-01-19
-
放假之前老大跟我提起了
时间:2021-01-19
-
数据库的运维计策剧本篇
时间:2021-01-19
热门文章
-
4.与聚合函数和 GROUP BY 子句有关的常见错
时间:2021-01-19
-
SQL Server安全(11/11):审核(Auditing)
时间:2021-01-09
-
sqlserver中查询横表变竖表的sql语句简析
时间:2020-12-08
-
SQL Server简单模式下误删除堆表记录恢复方
时间:2020-12-12
-
关于SQL Server查询语句的使用
时间:2020-12-13
-
MSSQL教程_mssql数据库教程_MSSQL基础教程_第
时间:2020-12-13
-
jdbc连接sql server数据库问题分析
时间:2020-12-10
-
详解SQL游标的用法
时间:2020-12-27
-
sql server 关于设置null的一些建议
时间:2020-12-28
-
mssql关于一个表格结构的另外一种显示(表
时间:2020-12-11
