惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
罗磊的独立博客
SecWiki News
SecWiki News
The Register - Security
The Register - Security
The GitHub Blog
The GitHub Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Schneier on Security
IT之家
IT之家
博客园 - 聂微东
T
The Exploit Database - CXSecurity.com
Recorded Future
Recorded Future
大猫的无限游戏
大猫的无限游戏
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Vercel News
Vercel News
G
GRAHAM CLULEY
D
DataBreaches.Net
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
博客园_首页
雷峰网
雷峰网
T
Tenable Blog
Spread Privacy
Spread Privacy
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
Cisco Talos Blog
Cisco Talos Blog
V
Visual Studio Blog
J
Java Code Geeks
博客园 - Franky
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
C
CERT Recently Published Vulnerability Notes
T
Threatpost
Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
P
Privacy International News Feed
T
Threat Research - Cisco Blogs
T
The Blog of Author Tim Ferriss
V
Vulnerabilities – Threatpost
Recent Announcements
Recent Announcements
Blog — PlanetScale
Blog — PlanetScale
Security Latest
Security Latest
U
Unit 42
M
MIT News - Artificial intelligence
Y
Y Combinator Blog
K
Kaspersky official blog
有赞技术团队
有赞技术团队
B
Blog
腾讯CDC

博客园 - 老D

.NET Memcached Client 扩展获取所有缓存Key 合并 GridView 的单元格 在Crystal Report中将数字转为英文 连接远程服务器共享 在代码中恢复sql server 数据库 - 老D 获取同一网段内的SQL SERVER实例 C#动态加载DLL Asp.net 文件下载 在网页处理按键事件 - 老D - 博客园 SQL语句导入导出大全 跨应用程序进行 Forms 身份验证 GridView导出Excel ASP.NET数据库连接字符串的加密与解密 ASP.NET中GridView动态绑定数据实现编辑更新 ASp.NET 2.0中Page事件的执行顺序 批量insert数据 简繁转换 ASP.NET应用程序开发 经典算法-C#四种排序算法
SQL Server 2005 中新CTE语法 递归性能测试
老D · 2008-09-04 · via 博客园 - 老D

     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牛人指教