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

推荐订阅源

U
Unit 42
S
Security Affairs
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
Microsoft Security Blog
Microsoft Security Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
美团技术团队
月光博客
月光博客
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
有赞技术团队
有赞技术团队
博客园 - 叶小钗
Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
腾讯CDC
C
Cisco Blogs
T
Tor Project blog
The Hacker News
The Hacker News
雷峰网
雷峰网
MyScale Blog
MyScale Blog
博客园 - 司徒正美
AWS News Blog
AWS News Blog
GbyAI
GbyAI
Y
Y Combinator Blog
D
DataBreaches.Net
Simon Willison's Weblog
Simon Willison's Weblog
S
Securelist
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
T
Tenable Blog
L
LangChain Blog
M
MIT News - Artificial intelligence
N
Netflix TechBlog - Medium
The Cloudflare Blog
A
About on SuperTechFans
IT之家
IT之家
F
Fortinet All Blogs
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
NISL@THU
NISL@THU
爱范儿
爱范儿
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
W
WeLiveSecurity
A
Arctic Wolf
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog

博客园 - 谢堂文(Darren Xie)

Camstar MES 5.8 發現Ajax事件失效 验证(C#和正则表达式) 新MES已上線 Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine Microsoft SQL Server Reporting Services (SSRS)报表技巧之在图表中增加参考线 MS SQL,数据库增长时众多表中谁是你关注的目标 想个法子找出性能差的SQL T-SQL 日期处理总结 从MS SQL删除大数据说开去 一步一步用C#写一个检查SQL Server假死警报服务 MM的Windows 7 登录密码忘记之后 基于工作实际需求的Ext.Net和C#搭配应用之一 取出网域(AD)中所有计算机名及位置描述等信息 MS SQL自定义字符串拆分函数的惨痛经历 2012,我的C#全能Excel操作(无需Office,不使用XML) 代码注释规范 2012年开发者该做的11件事 取出AD中一個組的所有成員信息(C#實現功能配合EXT做的界面) 一個文件文件和路徑的類 C#路径/文件/目录/I/O常见操作汇总
SQL调优日记之发挥SQL性能与你的写法有关--对比三种方式实现相同功能
谢堂文(Darren Xie) · 2012-05-15 · via 博客园 - 谢堂文(Darren Xie)

今天再次改老系统,看着前边的师兄留下的SQL,就想起了MS SQL 7.5和SQL2000。可能很多人都还没有习惯新版本(05版之后)的SQL语法,还是用以前开发MS SQL2000的方式实现功能,但是多少人会明白,换一种写法后,性能却相差十倍百倍呢!

我用来做例子的是我们MES系统用到的一段简单功能T-SQL,都是使用同一个库、相同的表、相同的逻辑:

开始前先记录时间,计算完成后看用了多少时间。

我先用推荐的语法来写的方式,代码1是好的写法,由于是在我们系统的情景下描述的,看管不可照抄,只说明性能的差别。

代码1:

用WITH,把各个逻辑分开处理,再终合出最后结果,推荐!

   1:  declare @P INT,@T DATETIME;
   2:  SELECT @P=1,@T=GETDATE();
   3:  ;WITH R0 --
   4:      AS (
   5:          SELECT TOP 1 M.WPCODE,t.RID,MACNO,LEFT(WFCNO,CHARINDEX('-',WFCNO)-1) WO FROM MES_WFCIO M,MES_WFCIODTL t  
   6:              WHERE M.RID=t.RID AND WFCNO='JSAC00334D-033-001'
   7:              ORDER BY t.RID DESC
   8:      )                
   9:      ,R1 
  10:      AS (
  11:          SELECT TOP 1 M.WPCODE,t.RID,M.MACNO,LEFT(WFCNO,CHARINDEX('-',WFCNO)-1) WO FROM MES_WFCIO M,MES_WFCIODTL t,R0
  12:              WHERE M.RID=t.RID 
  13:              AND M.MACNO=R0.MACNO
  14:              AND M.RID<>R0.RID
  15:              AND M.WPCODE=R0.WPCODE
  16:              ORDER BY t.RID DESC
  17:      )
  18:      ,R2 
  19:      AS (
  20:          SELECT WO FROM R0
  21:          UNION
  22:          SELECT WO FROM R1
  23:      )
  24:      ,R3 
  25:      AS (
  26:          SELECT DISTINCT MASTERNUM FROM R2,WO WHERE R2.WO=WO.WONUM
  27:      )
  28:      SELECT @P=COUNT(*) FROM R3;
  29:      select @P AS [計算結果1];
  30:  SELECT DATEDIFF(ms,@T,getdate()) as [方法1用時];

代码2:

这是2000的时候多数人用的方式,计算过程多用临时表,不推荐!

   1:  declare @P INT,@T DATETIME;
   2:  SELECT @P=1,@T=GETDATE();
   3:  SELECT TOP 1 M.WPCODE,t.RID,MACNO,LEFT(WFCNO,CHARINDEX('-',WFCNO)-1) WO 
   4:      INTO #R0
   5:      FROM MES_WFCIO M,MES_WFCIODTL t  
   6:      WHERE M.RID=t.RID AND WFCNO='JSAC00334D-033-001'
   7:      ORDER BY t.RID DESC;
   8:   
   9:  SELECT TOP 1 M.WPCODE,t.RID,M.MACNO,LEFT(WFCNO,CHARINDEX('-',WFCNO)-1) WO 
  10:      INTO #R1
  11:      FROM MES_WFCIO M,MES_WFCIODTL t,#R0 R0
  12:      WHERE M.RID=t.RID 
  13:      AND M.MACNO=R0.MACNO
  14:      AND M.RID<>R0.RID
  15:      AND M.WPCODE=R0.WPCODE
  16:      ORDER BY t.RID DESC;
  17:   
  18:  SELECT WO INTO #R2 FROM #R0
  19:  UNION
  20:  SELECT WO FROM #R1;
  21:   
  22:  SELECT DISTINCT MASTERNUM 
  23:      INTO #R3
  24:       FROM #R2 R2,WO 
  25:      WHERE R2.WO=WO.WONUM;
  26:   
  27:  SELECT @P=COUNT(*) FROM #R3;
  28:  select @P AS [計算結果2];
  29:  SELECT DATEDIFF(ms,@T,getdate()) as [方法2用時];
  30:   
  31:  drop table #R0,#R1,#R2,#R3;

代码3:

强逻辑人员的写法,子查询方式,不推荐!

   1:  declare @P INT,@T DATETIME;
   2:  SELECT @P=1,@T=GETDATE();
   3:  SELECT @P=COUNT(*) 
   4:      FROM (SELECT DISTINCT MASTERNUM 
   5:          FROM (SELECT WO 
   6:                  FROM (SELECT TOP 1 M.WPCODE,t.RID,MACNO,LEFT(WFCNO,CHARINDEX('-',WFCNO)-1) WO 
   7:                          FROM MES_WFCIO M,MES_WFCIODTL t  
   8:                          WHERE M.RID=t.RID AND WFCNO='JSAC00334D-033-001'
   9:                          ORDER BY t.RID DESC) x
  10:                      UNION
  11:                      SELECT WO FROM (SELECT TOP 1 M.WPCODE,t.RID,M.MACNO,LEFT(WFCNO,CHARINDEX('-',WFCNO)-1) WO 
  12:              FROM MES_WFCIO M,MES_WFCIODTL t,(SELECT TOP 1 M.WPCODE,t.RID,MACNO,LEFT(WFCNO,CHARINDEX('-',WFCNO)-1) WO 
  13:                  FROM MES_WFCIO M,MES_WFCIODTL t  
  14:                  WHERE M.RID=t.RID AND WFCNO='JSAC00334D-033-001'
  15:                  ORDER BY t.RID DESC) R0
  16:              WHERE M.RID=t.RID
  17:              AND M.MACNO=R0.MACNO
  18:              AND M.RID<>R0.RID
  19:              AND M.WPCODE=R0.WPCODE
  20:              ORDER BY t.RID DESC)R1) R2,WO 
  21:          WHERE R2.WO=WO.WONUM)R3;
  22:  select @P AS [計算結果3];
  23:  SELECT DATEDIFF(ms,@T,getdate())  as [方法3用時];

看看执行的结果对比:

第一种写法用时不到1毫秒;

第二种写法用时56毫秒;

第三种写法用时不到1毫秒;

image

再单独执行,代码1用了3毫秒,从Messages中看到只有两条信息,也就是只操作了两个结果表对象;

image

image

代码2用了63毫秒,从Messages中看到只有两条信息,也就是只操作了六个结果表对象;

image

image

代码3用了3毫秒,从Messages中看到只有两条信息,也就是只操作了两个结果表对象;

image

image

从以上的对比结果来看,用with和用子查询的方式性能差不多,但是子查询的写法代码很难维护,用WITH的方式逻辑明确,代码重用高,易维护,性能优越;用临时表的方式逻辑也明确,但是性能差。用WITH和用子查询的方式都可以用到SQL的同时执行,用临时表就只能是按顺序执行了。

当你要对SQL进行性能调优时,除了考虑索引、统计信息、分区表、硬件升级和归档数据外,也建议考虑评估SQL的写法。

原创,转载请注明出处:http://www.cnblogs.com/YIYUMENG