SQL-Server查询性能优化.docx_第1页
SQL-Server查询性能优化.docx_第2页
SQL-Server查询性能优化.docx_第3页
SQL-Server查询性能优化.docx_第4页
SQL-Server查询性能优化.docx_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

SQL Server查询性能优化查询性能调整已经是数据库应用程序的重要组成部分.使用正确的查询性能调整方法,常常可以大大节省时间和金钱,提高用户体验.一、 SQL查询性能调整1. 性能调优的整程性能调整是一个迭代过程:识别主要的瓶颈,试图解决它们,测试修改后的效果,并返回到开始步骤,知道性能可以接受.在解决瓶颈的过程中,应该遵循每次只做一次改动的原则.因为修改会影响到系统的其它部分,所以必须重新评估每次修改对系统总体性能的影响.图:性能调整过程2. 影响SQL Server性能方面在已经优化了硬件,操作系统和SQL Server设置的情况下,影响SQL Server中的性能的方面按照粗略的顺序(最糟糕的首先出现)排序如下:(1) 低质量的索引(2) 不精确的统计(3) 过多的阻塞和死锁(4) 不基于数据集的操作(5) 低质量的查询设计(6) 低质量的数据库设计(7) 过多的碎片(8) 不可重用的执行计划(9) 低质量的执行计划(10) 频繁重编译计划(11) 游标的错误使用(12) 错误配置数据库日志(13) 过多使用或错误配置tempdb二、 SQL查询性能分析1. SQL Profiler工具SQL Profilter是一个可用于以下目标的GUI工具: 图形化监视SQL Server查询 在后台收集查询信息 分析性能 诊断像死锁这样的问题 调试Transact-SQL语句 模拟重放SQL Server活动打开步骤:开始菜单-SQL Server 2008 R2 - 性能工具,选择SQL Server Profiler.如下图:打开后,创建一个跟踪,如下图运行后,如下图:2. 识别开销最大的查询识别开销最大的查询时重点关注以下几个点:CPU,内存和I/O.CPU表示用于执行查询的CPU时间.Reads表示一个查询操作的逻辑页面(大小为8K)的数量.从而指出查询产生的内存压力.同时一定程度上指出了磁盘的压力.因为内存页面必须在查询操作的过程中北备份,在第一次数据访问的时候被写入,并且在内存瓶颈时被写到磁盘上.查询的逻辑读数量越大,造成磁盘压力的可能性就越大.而且,过多的逻辑页面也增加了CPU用于管理这些页面的负载.I/O表示对磁盘的读写.对于一个成本效益较高的执行计划来说,最小化I/O的数量不是一个必要的条件,但是经常可以发现,开销最低的计划有很少的I/O.3. 识别运行缓慢的查询为了发现执行缓慢的查询,在Duration列上分组跟踪输出.4. 查询执行计划执行计划是显示查询优化器执行查询所所以用的处理策略(包含多个中间步骤).如何查看一个SQL语句的执行计划.在SQL Server查询工具的工具栏中点击”显示估计的执行计划”,或者使用快捷键”Ctrl+L”.可以在”查询选项”中勾选统计分析选项,帮助分析执行计划.查询执行计划的阅读顺序是从右到左,从上到下.每个步骤代表获得查询最终输出所执行的一个操作.由执行计划表示的查询执行的一些特征如下:l 如果查询由多个查询的批组成,每个查询的执行计划按照执行的顺序显示.批中的每个执行计划将有一个相对的估算开销,整个批的总开销为100%.比如:Select * from ac_user; select * from MaterialCalculation;l 执行计划中的每个图标代表一个操作符.它们每个都有一个相对的估算开销,执行计划中的所有节点的总开销是100%l 执行计划中的一个起始操作符通常表示一个数据库对象(表或索引)的数据检索机制.l 数据检索通常是一个表操作或一个索引操作.l 索引上的数据检索的命名惯例是表名.索引名l 数据从右到左在两个操作符之间流动,有一个连接箭头表示.连接箭头的宽度是传输行数的图形表示.l 同一列的两个操作符之间的连接机制将是嵌套的循环连接,hash匹配连接或是合并连接.l 将光标放置在执行计划中的一个节点之上,显示一个具有一些细节的弹出窗口.l 在属性窗口中有完整的一组关于操作符的细节,可以右键单击操作符并选择属性来显示.l 操作符细节在顶部显示物理和逻辑操作的类型.物理操作代表存储引擎实际使用的,而逻辑操作室优化器用于建立估算执行计划的结构.l 操作符细节弹出窗口的参数部分在分析中特别有用,因为她显示了优化器所使用的过滤或连接条件.5. 识别执行计划中开销最大的步骤可以通过以下的方式选择开始步骤: 查看执行计划中开销最大的节点. 如果执行计划来自于一个批语句,可能查找开销最大的语句. 查看节点间连接箭头的宽度.非常宽的连接箭头表示对应节点之间传输大量的行.分析箭头左边节点并理解为什么需要这么多行.还要检查箭头的属性,可能看到的估计的行和实际的行不一样,这可能是由过时的统计造成的.SELECT mc.StyleDocTreeID , mcd.MaterialCalculationIDFROM MaterialCalculationDetail mcdLEFT JOIN MaterialCalculation mc ON mc.ID = mcd.MaterialCalculationID 寻找hash连接操作.对于小的结果集,嵌套的循环连接通常是首选. 寻找书签操作操作.对于结果集的书签操作可能造成大量的逻辑读. 寻找有感叹号表示警告的操作符,这是需要立刻注意的地方.通常解决警告的情况将对性能有所帮助. 寻找执行排序操作的步骤.这表示数据没有以正确的排序进行检索.6. 数据的3中连接类型 嵌套循环连接 合并连接 Hash连接3者之间的性能比较(按性能从高到低):嵌套循环连接 合并连接 Hash连接三、 索引分析1. 聚集索引与非聚集索引索引是由具有如下特征的一棵树所组成的:唯一的,作为遍历起始点的根分页,可能存在的中间索引层次以及底层的叶子分页.所用索引可以找到正确的叶子分页.索引的中间层次是根据表的行数以及索引行的大小而变化的.如果使用一个较长的键来创建索引,一个分页上就只能容纳较少的条目,因而改索引就需要更多的分页(或者说更多层).对于任何索引,无论是聚集索引还是非聚集索引,叶级别都是按照键的顺序由所有的键值组成的(对于复合索引,就是若干键值的组合).并已B-树的结构存储.B-树结构聚集索引的叶级别不仅包含了索引键,还包含数据页.也就是说,每行的所有字段都在叶级别中.聚集索引中键值的顺序与表中数据的顺序一致.表中数据页是通过一个被称作”页链”的双向链表来维护的(堆中的页不是链接在一起的).页链中叶顺序以及数据页上的记录的顺序就是索引键的顺序.由于实际数据页的页链只能按一种方式排序,因此一张表只能有一个聚集索引.单个分区中聚集索引的结构非聚集索引页级别不包含任何全部的数据.除了键值以外,每个叶级别中的索引行包含了一个书签,告诉SQL可以在哪里找到与索引键相应的数据行.一个书签可能有两种格式.如果表上存在聚集索引,书签就是相应的数据行的聚集索引键.如果是堆表结构(就是没有聚集索引的情况下),书签就是一个行标示符(row identifier,RID),以”文件号:叶号:槽号”的格式来定位实际的行.由于非聚集索引的存在与否并不影响数据分页组织,因此每张表上并不像聚集索引那样只能拥有一个非聚集索引.每张表能够包含最多999(SQL 2005为249)个非聚集索引,但实际用到的比这个数要少得多.单个分区中非聚集索引的结构聚集索引和非聚集索引之间的最大区别在于除了索引键以外叶级别还存放了什么.聚集索引中查找行非聚集索引中查找行2. 索引的好处和索引的开销减少磁盘I/O和逻辑读次数的最佳方法之一就是使用索引.索引允许SQL Server在表里查询数据而不需要扫描整个表.索引给性能带来的好处有一定的代价.有索引的表需要更多的存储和内存空间以容纳表的数据页之外的索引页面.数据操作Insert,Update,Delete可能要花费更长的时间.3. 索引设计建议 检查Where子句和连接条件列当一个查询语句提交后,SQL Server将按一下步骤进行操作:(1) 优化器识别Where子句和连接条件中包含的列(2) 接着优化器检查这些列上的索引(3) 优化器通过从索引上维护的统计确定子句的选择性(也就是返回多少行)评估每个索引的有效性(4) 最终优化器根据前面几个步骤中收集的信息,估计读取所限定的行开销最低的方法. 使用窄索引可以在表中的一个列组合上创建索引.如果一个索引中包含的列在12之间,就叫窄索引,大于2列的称为宽索引. 检查列的唯一性在一个具有很小范围的可能值的列(如性别等)上创建索引对性能没有好处,因为查询优化器将不能使用索引有效地减少返回的行. 检查列的数据类型为了最好的性能,尽量在索引中使用较少的列.还应该避免在索引中使用宽数据类型的列.比如:Char,Varchar,NChar和NVarchar等. 考虑列的顺序索引键值在索引的第一列上排序,然后在前一列的每个之中一下一列做子排序. 考虑索引类型(聚集索引或非聚集索引)聚集索引和非聚集索引都是B-树结构,两者之间的主要区别是聚集索引中叶子页面时表的数据页面,因此数据和指针的顺序相同,这意味着聚集索引就是该表.而非聚集索引叶子页面存储的是执行聚集索引的地址或表记录行的地址.速度没有聚集索引快,但每张表只能有一个聚集索引.4. 聚集索引的建议(1) 首先创建聚集索引因为所有非聚集索引是在其索引行上保存聚集索引键,所以非聚集索引和聚集索引创建的顺序非常重要.如果非聚集索引先于聚集索引创建,那么非聚集索引行定位器将包含指向表中对应RID的指针.稍后创建聚集索引将修改所有非聚集索引,将聚集索引键作为新的行定位器值.这实际上重建了所有非聚集索引.(2) 保持窄索引为了最佳性能,应使聚集索引的总体长度尽可能的小.整数数据类型的列通常是聚集索引的较好候选者,而字符串数据类型列决不是最佳的选择.(3) 一步重建聚集索引因为非聚集索引对聚集索引的依赖性,用单独的Drop Index和Create Index语句重建聚集索引将导致所有的非聚集索引被建立两次.为了避免这种情况,使用用Create Index语句的Drop_Existing子句重建聚集索引.(4) 何时使用一个聚集索引 检索一定范围的数据 读取预先排序的数据(5) 何时不使用聚集索引 频繁更新的列 宽的关键字5. 非聚集索引及书签查找当一个查询请求不是优化器选择的非聚集索引一部分的列时,需要一个查找.这对于一个聚集索引来说是一个关键字查找,对于一个堆表来说是一个RID查找.这也叫书签查找.(1) 何时使用非聚集索引 频繁更新的列 宽关键字(2) 何时不使用非聚集索引 检索大量行的查询(用聚集索引更好)6. 高级索引技术(1) 覆盖索引覆盖索引是在所有为满足SQL查询不用到达基本表所需的列上建立的非聚集索引.这时我们可以创建一个符合索引来实现.也可以使用Include操作符来实现.Include最好在一下情况中使用: 你不希望增加索引键的大小,但是仍希望有一个覆盖索引 你打算索引一种不能被索引的数据类型(文本,ntext和图像除外) 你已经超过了一个索引的关键字列的最大数量(最好避免这种情况)(2) 索引交叉如果一个表有多个索引,那么SQL Server可以使用多个索引来执行一个查询.根据每个索引选择的小的数据子集,然后执行两个子集的一个交叉(即:只返回满足条件的那些行.)(3) 索引连接索引连接就是将索引覆盖技术应用到索引交叉.如果没有单个覆盖查询的索引而多个索引一起可以覆盖该查询,SQL Server可以使用索引连接来完成满足查询而不需要转到基本表.(4) 过滤索引过滤索引是使用过滤器的非聚集索引.这个过滤器基本上是一个Where子句.四、 查询设计分析一般来说,以下的一些建议能确保最佳性能(1) 在小的结果集上操作在Select语句的选择列表中使用最小的列集,不要使用输出结果集中不需要的列.例如:不要使用Select *返回所有列.Select * 语句是覆盖索引无效,因为在索引中包含所有列是不现实的.(2) 有效使用索引 避免不可参数化的搜索条件可参数化的搜索条件一般能是优化器使用Where子句中引用的列上的索引.而不可参数化的搜索条件一般会阻止使用Where子句中引用的列上的索引.常见的可参数化和不可参数化的搜索条件类型搜索条件可参数化包含条件=,=,=和between,以及一些Like条件(like abc%)不可参数化排除条件,!=,!,!,Not Exists,Not In和Not Like In,Or,以及一些Like条件(like %abc) 避免在Where子句列上使用算术运算符Where子句中的列上使用运算符可以阻止优化器使用该列上的索引.例如:Select * from Table Where ID * 2 = 100 避免在Where子句列上使用函数Where子句中的列上使用函数也阻止优化器使用该列上的索引.例如Select a.Name from Table Where SUBTRING(a.Name,1,1) = F 尽量使用Inner Join,少用Outer Join比如有如下两张表:l Inner Join产生的结果是AB的交集SELECT * FROM TableAINNER JOINTableB ON TableA.name = TableB.namel Left Outer Join产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代.SELECT * FROM TableALEFT OUTER JOINTableB ON TableA.name = TableB.namel Right Outer Join产生表B的完全集,而A表中匹配的则有值,没有匹配的则以null值取代.SELECT * FROM TableA RIGHT OUTER JOINTableB ON TableA.name = TableB.name图标如left join类似。SQL的查询性能与查询的数据量密切相关.使用Outer Join意味着必须对左右两个表查询所有行,如果表很大而没有相应的Where语句,那么Outer Join很容易导致table scan或index scan,而Inner Join返回的是两个关联表的交集,正常情况下返回的数据量要比使用Outer Join返回的数据量少,而且使用Inner Join可以避免全表扫描.如果数据量大,还会导致外部输入表和内部输入表之间以Hash连接方式进行连接,而Hash连接是3种连接方式(嵌套循环连接,合并连接,Hash连接)中性能最低的一个.(3) 避免资源密集型的查询 避免数据类型转换 使用Exists代替Count(*)来验证数据存在 使用Union All代替Union 为聚合和排序操作使用索引五、 常用提高查询速度的SQL语句写法 应尽量避免在where子句中使用!=或操作符,否则将引擎放弃使用索引而进行全表扫描。 对查询进行优化,应尽量避免全表扫描,首先应考虑在where及orderby涉及的列上建立索引。 应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:selectidfromtwherenumisnull可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:selectidfromtwherenum=0 应尽量避免在where子句中使用or来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:selectidfromtwherenum=10ornum=20可以这样查询:selectidfromtwherenum=10unionallselectidfromtwherenum=20 下面的查询也将导致全表扫描:(不能前置百分号)selectidfromtwherenamelike%abc% in和notin也要慎用,否则会导致全表扫描,如:selectidfromtwherenumin(1,2,3)对于连续的数值,能用between就不要用in了:selectidfromtwherenumbetween1and3selectxx,phoneFROMsendaJOIN(selechoneunionselecNIONSELECbona.Phone=b.phone替代下面很多数据隔开的时候in13992085916 应尽量避免在where子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:selectidfromtwherenum/2=100应改为:selectidfromtwherenum=100*2 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:selectidfromtwheresubstring(name,1,3)=abc应改为:selectidfromtwherenamelikeabc% 不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。 很多时候用exists代替in是一个好的选择:selectnumfromawherenumin(selectnumfromb)用下面的语句替换:selectnumfromawhereexists(select1frombwherenum=a.num) 并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。 索引并不是越多越好,索引固然可以提高相应的select的效率,但同时也降低了insert及update的效率,因为insert或update时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。 应尽可能的避免更新clustered索引数据列,因为clustered索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新clustered索引数据列,那么需要考虑是否应将该索引建为clustered索引。 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。 尽可能的使用varchar/nvarchar代替char/nchar,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。 任何地方都不要使用select*fromt,用具体的字段列表代替“*”,不要返回用不到的任何字段。 避免频繁创建和删除临时表,以减少系统表资源的消耗。 在新建临时表时,如果一次性插入数据量很大,那么可以使用selectinto代替createtable,避免造成大量log,以提高速度;如果数据量不大,为了缓和系统表的资源,应先createtable,然后insert。 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncatetable,然后droptable,这样可以避免系统表的较长时间锁定。 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。 使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。 与临时表一样,游标并不是不可使用。对小型数据集使用FAST_FORWARD游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。 在所有的存储过程和触发器的开始处设置SETNOCOUNTON,在结束时设置SETNOCOUNTOFF。无需在执行存储过程和触发器的每个语句后向客户端发送DONE_IN_PROC消息。 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。 尽量避免大事务操作,提高系统并发能力。六、 操作实例1. 和诚0832.材料送外加工合同待处理查询:SELECT p.ProviderNo,p.Relation1 as Relation,m.FactoryMaterial,mcs.code as MSCode,p.TelephoneNo as Phone,p.FaxNo as Faxs,vs.WarehouseID,fw.code as WarehouseCode,p.Buyer,p.ProviderCharacter,c.MaterialCalculationID as ID,vs.UID as OrderDocUID,c.StyleDocTreeID,c.MaterialCalculationID,c.IndexCount, m.MaterialCategoryID,c.MaterialID,inf.Code as FactoryCode,CONVERT(VARCHAR(10),c.SubmitDate ,120) as SubmitDate,c.ShipMentDate, vs.DocCode as OrderCode,vs.Code as StyleCode,vs.Name as StyleName,vs.CustomStyleCode,vs.CustomClothBrand,vs.NameEn as StyleNameEn,vs.Editionhandle,vs.CuttingNo,vs.OrderDocType,vs.DocType, vs.ModelNo,vs.OperateDate,vs.SessionType,c.MaterialCalculationCode,c.MaterialCalculationName, vs.CustomName,vs.CustomAbCode,vs.OperateDept as OperateDept,vs.OperatePerson as OperatePerson,c.PlanPerson,c.PartName,m.Type as MaterialType,c.HandedPerson, c.MaterialCalculationDetailID,op.ID as OrderMaterialPriceID,vs.FactoryID as StyleFactoryID,vs.WarehouseID as StyleWarehouseID, Cast(Isnull(op.Price,c.Price) as real) as Price, Isnull(p.MonetaryUnit,c.MonetaryUnit) as MonetaryUnit, om.SubmitDate as OrderMaterialPriceSubmitDate,om.CheckState as OrderMaterialPriceCheckState,inf.ID as OrderSendFactoryID, c.RequireDate,c.EachExpend,Cast(c.OrderCount as real) as OrderCount,Cast(c.OrderMaterialCount as real) as OrderMaterialCount,Cast(c.Count as real) as Count, Cast(sm.Count as decimal(18,2) as HasPurchaseCount,c.PurchaseType,m.PurchaseUnit, m.UnitNo as MaterialUnitNo,c.Destination,c.EndDestination, cast(c.Count-ISNULL(sm.Count,0) as real) as RemainCount, Cast(sm.DecreaseCount as real) as DecreaseCount,Cast(sm.OverloadCount as real) as OverloadCount, m.Class as MaterialClass,m.SubClass as MaterialSubClass,m.QuotedPriceClass as MaterialQuotedPriceClass, m.CodePrefix as MaterialCodePrefix,m.Name as MaterialName,m.EnName as MaterialEnName,m.Code as MaterialCode,m.Color as MaterialColor,c.MaterialQuality,m.Element as Element, prem.CodePrefix as PrevMaterialCodePrefix,prem.Code as PrevMaterialCode,prem.Name as PrevMaterialName, m.Density as MaterialDensity,m.Minification as MaterialMinification, m.Spec as MaterialSpec,m.DesignRemark,m.Breadth as MaterialBreadth,m.IsSampleCode,vms.Name as MaterialOutSourcingClass, m.Attribute as MaterialAttribute,isnull(op.Provider,c.Provider) as ProviderID,isnull(op.ProviderPurchaseAreaID,c.ProviderPurchaseAreaID) as ProviderPurchaseAreaID, c.PrevProviderPurchaseAreaID,Isnull(c.ProviderType,80) as ProviderType, c.HasHanged,c.LastModifiedUserID,c.LastModifiedDate,c.Remark,c.MaterialOutSourcingRemark,c.DataFromType as DataFromTypeID, CASE c.DataFromType WHEN 0 THEN 主动需求计划 WHEN 1 THEN 跟单需求计划 ELSE BOM表 END AS DataFromType, c.DocMaterialCalculationType as MaterialCalculationType, CASE ISNULL(sm.MaterialCalculationDetailID,0) WHEN 0 THEN 0 ELSE 1 END as ImageStateMark,mcs.SubmitDate as SureSubmitDate,m.ColorNameEN,m.SizeNameEN,mt.Code as MaterialTypeCode,vs.MainMaterialName FROM view_GetMaterialForPurchase c (NOLOCK) INNER JOIN view_MXMaterial m (NOLOCK) ON m.ID = c.MaterialID LEFT JOIN view_MXMaterial prem (NOLOCK) ON prem.ID = c.PrevMaterialID LEFT JOIN view_MaterialClass vc (NOLOCK) ON m.Class = vc.ID LEFT JOIN view_MaterialOutSourcingClass vms (NOLOCK) on vms.ID = m.OutSourcingClass LEFT JOIN MX_MaterialCategoryImage mi (NOLOCK) on mi.MaterialCategoryID = m.MaterialCategoryID INNER JOIN view_OrderStyleExtend vs (NOLOCK) ON vs.StyleDocTreeID = c.StyleDocTreeID LEFT JOIN view_Factory inf (NOLOCK) ON inf.ID = vs.FactoryID LEFT JOIN Provider p (NOLOCK) ON c.Provider = p.ID LEFT JOIN (SELECT SUM(c.Count + isnull(c.UsefulStockCount,0) + isnull(c.UsefulOnwayCount,0) as Count,SUM(c.Count*Isnull(c.OverloadPercent,0)/100) as OverloadCount, Sum(c.Count*Isnull(c.DecreasePercent,0)/100) as DecreaseCount,MaterialCalculationDetailID FROM PurchaseShipMaterial c (NOLOCK) INNER JOIN PurchaseDocTree t (NOLOCK) on c.DocTreeID = t.ID INNER JOIN PurchaseDoc p (NOLOCK) on t.DocCode = p.UID INNER JOIN view_MXMaterial m (NOLOCK) ON m.ID = c.MaterialID WHERE p.PurchaseDocDataFromType IN (100,102) AND m.Type = 62 group by c.MaterialCalculationDetailID ) sm ON c.MaterialCalculationDetailID = sm.MaterialCalculationDetailID LEFT JOIN OrderMaterialPriceDetail op (NOLOCK) on c.MaterialCalculationDetailID = op.MaterialCalculationDetailID LEFT JOIN MaterialCalculationSure mcs (NOLOCK) on mcs.ID = c.MaterialCalculationSureID LEFT JOIN OrderMaterialPrice om (NOLOCK) ON om.ID = op.OrderMaterialPriceID LEFT JOIN view_MaterialSubClass sc (NOLOCK) on m.SubClass = sc.ID LEFT JOIN view_GoodsType vg (NOLOCK) on vg.ID = vs.GoodsType LEFT JOIN view_Custom vcm (NOLOCK) on vcm.ID = vs.CustomID LEFT JOIN selectinfo mt (NOLOCK) on mt.ID = m.Type LEFT JOIN FactoryWarehouse fw on fw.id=vs.WarehouseID WHERE m.Type = 62 and c.ProviderType = 80 AND vs.OrderDocType IN (0,90,91,92,93,98,107) AND (c.SubmitDate between Cast(2014-03-14 as Datetime) AND Cast(2014-03-22 as Datetime) AND (sm.Count IS NULL OR c.Count sm.Count ) AND c.HasHanged =0 AND c.MaterialIsOutSourcing = 1 AND vc.IsFormulaColor = 0 and isnull(c.ProviderPurchaseAreaID,0) in(3178,3179,3180,3181,3183,3184,3185,3186,3187,3188,3189,3190,3194,3195,3295,35592,35593,35594,0)2. 和诚0911.采购暂收待处理查询语句:SELECT CASE WHEN Cast(a.PurchaseCount-Isnull(pm.HasReceiveCount,0)+Isnull(mr.Count,0)/a.ConvertRate as Decimal(18,4)0 THEN 0 ELSE 1 END as ImageStateMark, pp.ProviderCharacter as ProviderCharacter,a.ID as PurchaseShipMaterialID,p.UID,p.Code,p.MonetaryUnit, p.ProviderName,m.Attribute as MaterialAttribute,vm.Name as MaterialAttributeName, a.ShipDocTreeID as ShipDocTreeID,p.DeliverDate,psd.RequireDate as PurchaseDocSureDeliverDate,psd.ColorSampleDate,psd.ShipSampleDate, vss.CustomPO,vss.CutNo,vss.ShipMentDate,vss.CustomNamePO,vss.POCustomNo,mc.DocMaterialCalculationType,a.Destination,a.EndDestination, DATEDIFF(dd,GetDate(),p.DeliverDate) as DelayNum,p.SubmitDate,p.Factory,p.WarehouseID as Warehouse,m.MaterialCategoryID, p.ExpectArriveDate,p.ShipRemark as PurchaseShipRemark,p.PurchasePerson,m.IsVerify,a.ProviderPurchaseAreaID, a.ID,a.MaterialID,a.StyleDocTreeID,os.DocCode as OrderCode,os.Code as StyleCode,os.CustomStyleCode,os.CustomClothBrand,os.NameEn as StyleNameEn,os.SessionType,os.CustomName, m.CodePrefix as MaterialCodePrefix,m.Name as MaterialName,m.EnName as MaterialEnName,Cast(null as Image) as MaterialImage,m.Code as MaterialCode,m.Color as MaterialColor, a.ColorNo,m.Spec as MaterialSpec,m.DesignRemark,m.Breadth as MaterialBreadth,m.Element as MaterialElement, a.Price ,a.PurchaseUnit,a.ConvertRate,a.HangPerson, Cast(a.PurchaseCount as Decimal(18,4)*(1+ISNULL(a.NotFinancePercent,0)/100) as PurchaseCount, Cast(Isnull(a.OReceiverPercent,0)*a.PurchaseCount/100 as Decimal(18,4) as OReceiverCount, Cast(isnull(a.DReceiverPercent,0)*a.PurchaseCount/100 as Decimal(18,4) as DReceiverCount, pm.HasReceiveCount,Cast(mr.Count/a.ConvertRate as Decimal(18,4) as MaterialReturnCount, Cast(a.PurchaseCount-Isnull(pm.HasReceiveCount,0)+Isnull(mr.Count,0)/a.ConvertRate as Decimal(18,4) as RemainReceiveCount,a.HasHanged,a.Remark, p.LastModifiedDate,p.LastModifiedMemo,p.PurchaseType,Isnull(vw.Name,) as WeeClassName ,isnull(m.IsMaterialBaseVerify,0) as IsMaterialBaseVerify,m.ColorNameEN,m.SizeNameEN,os.MainMaterialName,a.OverloadCount,c.Name as PayAccount,a.OverloadPercent, a.NotFinancePercent,Cast(a.PurchaseCount*ISNULL(a.NotFinancePercent,0) as decimal(18,2) as NotFinanceCount FROM (select * from PurchaseShipMaterial a (NOLOCK) where ID= 441831) a INNER JOIN view_PurchaseShipExtend as p (NOLOCK) ON p.DocTreeID = a.DocTreeID LEFT JOIN Company c (NOLOCK) on c.id = p.account LEFT JOIN Provider pp (NOLOCK) on p.ProviderID=pp.ID LEFT JOIN MaterialCalculation mc (NOLOCK) on a.MaterialCalculationID = mc.ID LEFT JOIN PurchaseDocSureDetail psd (NOLOCK) on a.ID = psd.PurchaseShipMaterialID INNER JOIN view_MXMaterial m (NOLOCK) ON a.MaterialID = m.ID L

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论