zoukankan      html  css  js  c++  java
  • SQL Server 2005 中新CTE语法 递归性能测试

         SQL Server 205针对数据操作语言DML增加了相当多的语法,例如 CTE,Pivot,UnPivot 等,今天想把以前的展开BOM(Bill of Materials)的旧方法用CET实现,看可不可以提高性能,测试最后还是不要动好。CET(Common table expression)兼具视图表和衍生数据表的能力。你可以视之为临时的视图表,或是在同一批处理查询语法中可重复使用的衍生数据表。

         先看下要测试的BOM结构,EL_NO是物料或半成品,BO_NO是EL_NO的上阶,BO_USE是用量,EL_INVID是表示是物料还是机种或成品,整张BOM表差不多5W行数据

    1.旧的递归方法

    ALTER FUNCTION [dbo].[f_bom_dal]
    (
     @bo_no   nvarchar(15)
    )
    RETURNS
     @r Table(  
       line  varchar(255),  
       el_no  nvarchar(15),    
       el_name nvarchar(20),  
       bo_use float,  
       el_invid nchar(1), 
       level  int, --层次  
       sid  varchar(255)) --排序字段,通过这个来排序,可以体现出树形的层次
    AS
    BEGIN
     declare   @l   int,  @ReStr as varchar(50)   
     select  @l=0,@ReStr='';

     insert   @r   select bo_no,el_no,el_name,1,el_invid,@l,@bo_no  
     from   Robo00_dal  
     where  bo_no=@bo_no and bo_use is null 
     while   @@rowcount>0  
     begin  
     set   @l=@l+1  
     insert   @r   select substring(Left(@ReStr,@l)+'├──────────────────',1,8),b.el_no,b.el_name,b.bo_use*r.bo_use,b.el_invid,@l,r.sid+'_'+b.el_no  
     from   robo00_dal b,@r   r  
     where   r.level=@l-1
     and   b.bo_no=r.el_no 
     and   b.bo_use>0  
     end
     RETURN
    END

    2.改用CET的方法SQL语句

    ALTER FUNCTION [dbo].[f_bom_dal_1]
    (
     @bo_no   nvarchar(15)
    )
    RETURNS
     @r Table(  
       line  varchar(255),  
       el_no  nvarchar(15),    
       el_name nvarchar(20),  
       bo_use float,  
       el_invid nchar(1), 
       level  int, --层次  
       sid  varchar(255)) --排序字段,通过这个来排序,可以体现出树形的层次
    AS
    BEGIN
     -- Fill the table variable with the rows for your result set
     WITH T(line,el_no,el_name,bo_use,el_invid,level,sid) AS(
      SELECT  bo_no,el_no,el_name,convert(float,1.0),el_invid,0,@bo_no from Robo00_dal where bo_no=@bo_no and bo_use is null 
      UNION ALL
      SELECT r.bo_no,r.el_no,r.el_name,convert(float,T.bo_use*r.bo_use),r.el_invid,T.level+1 level,r.el_no sid FROM ROBO00_dal r INNER JOIN T ON r.bo_no=T.el_no and r.bo_use>0   
     )
     INSERT INTO @r SELECT * FROM T

     RETURN
    END

    测试结果:

    从图可以看出用旧的 While 方法只用了 453ms,而新的的CTE递归用了8530ms,测试同一机种,返回的结果都是646行(即这个机种用了多少个半成品或物料)

    细心的朋友可能会发现,两种方法返回的结果(line和sid列)不一样,是的。因为CTE递归创建数据时,不变成员和递归成员的数据结构要完全一样,包括数据类型、长度与精确位数(不然会通不过编译,如下图,用老方法就没这个规定)。如果要把CTE递归返回的结果要和旧的一样line显示层次结构、sid显示物料层次,那还要用Convert把line和sid在递归部分给改上,如果再用Convert,那CTE会不会更慢?我也懒得试了

    从执行时间看453和8530根本不在同等级,不知道是不是我CTE的用法不对,还是什么原因,因为我想MS不会出现这样低级的错误吧,望各位sql牛人指教

  • 相关阅读:
    BLE 5协议栈-安全管理层
    BLE 5协议栈-通用属性规范层(GATT)
    BLE 5协议栈-属性协议层(ATT)
    BLE 5协议栈-逻辑链路控制与适配协议层(L2CAP)
    BLE 5协议栈-主机控制接口(HCI)
    BLE 5协议栈-直接测试模式
    BLE 5协议栈-链路层
    BLE 5协议栈-物理层
    名词缩写
    C#中数据库事务、存储过程基本用法
  • 原文地址:https://www.cnblogs.com/elzero/p/1283738.html
Copyright © 2011-2022 走看看