日期:2014-05-18 浏览次数:20626 次
/***************************************************************************/ ----------------------------------------- -- Title :由一条语句优化引发的思考 -- Author :小爱 -- Date :2012-03-30 19:06:10 -- Version: -- Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) -- Apr 2 2010 15:48:46 -- Copyright (c) Microsoft Corporation -- Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7600: ) ----------------------------------------- /***************************************************************************/ --> 测试数据:[tb] if object_id('[tb]') is not null drop table [tb] go create table [tb]([id] int,[num] int,[s] int) insert [tb] select 1,2,5 union all select 1,2,5 union all select 1,2,5 union all select 1,3,5 union all select 2,2,5 union all select 2,3,5 union all select 3,4,5 ---直接上结果,描述起来一时半会说不清 /* id cnt sums ----------- ----------- ----------- 1 2 20 2 2 10 3 1 5 */ ----------------------------------------- --下面的语句是原著 --1 set statistics io on select id,count([num])as cnt ,sum([s]) as sums from( select id,[num],sum([s]) as [s] from [tb] group by [id],[num] ) t group by id --当本人目测良久只后写下了下面的语句 --2 select id,count(distinct [num]) as cnt,sum([s])as sums from tb group by id --当我自认为自己很牛逼哄哄,写下了如此简练的语句 --原著也觉得我是个人才,佩服的不得了的时候 --我按下了Ctrl+L --令我大吃一惊的事情发生了 --方法2的开销要比1 大好多 --在看IO,omg的,2比1大 --这让我情何以堪啊 --回头认真思考问题所在,难道是 count(distinct[num]) 这一步的问题? --好吧,我去掉了distinct 关键字,ps:暂不讨论结果是否一致 --果然这次从各方面看问题2比1 都更优越,但这结果都不一样啊, --问题:count(distinct col) 使用distinct关键字 效率会很低? --先不要往下定论,看下面的,我去掉sum操作 select id,count([num])as cnt from( select id,[num] from [tb] group by [id],[num] ) t group by id --2 select id,count(distinct [num]) as cnt from tb group by id --这次又发现,这两个语句的执行计划一模一样,这又是为什么呢? --这个时候我又想到了索引 alter table tb add ix int identity(1,1) primary key --在执行上面的语句 --你们猜有没有走索引路线呢?这又是为什么呢? --到这里简单的总结一下 -----------------------------------------我隔---------------------------------------- --1、不是最简洁的语句效率就最好 --2、不是所有的子查询都慢 --3、没有全面的测试不要妄下结论,如果我只认为distinct关键字会影响效率那么,那么那么... --4、性能调优的道路还很漫长 ----------------------------------------我再隔---------------------------------------- --最后告诉大家一个小秘密 --1、在线上90w的表中,这两个语句的查询开销和用时差异并不大,当然前者更优异 --2、表一定要有个主键,否则普通索引的利用是很差的,除非是极少用来查询的表。
select id,count([num])as cnt ,sum([s]) as sums from( select id,[num],sum([s]) as [s] from [tb] group by [id],[num] ) t group by id --当本人目测良久只后写下了下面的语句 --2 (1 行受影响) StmtText ----------------------------------------------------------------------------------------- |--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(int,[Expr1021],0), [Expr1006]=CASE WHEN [Expr1022]=(0) THEN NULL ELSE [Expr1023] END)) |--Stream Aggregate(GROUP BY:([tempdb].[dbo].[tb].[id]) DEFINE:([Expr1021]=COUNT([