当前位置:编程学习 > C#/ASP.NET >>

(急)两段sql查询语句性能的比较和sql执行计划中的“表假脱机”?

1、sql执行计划中的“表假脱机”是什么意思?执行机制是怎么样的?
2、两段sql查询语句执行后的目的是一样的,两条语句都没有错,
   问题是 这两条语句的性能差别在哪?原因是什么?

--语句1:
select top 1 A.UserId,A.Phone,B.CodeId,Cmd,Addr,key1,key2,RContent,B.FeeMode from dbo.[V_AddFeePhoneUser] A  WITH(NOLOCK),
(
select A.AreaId,A.FeeMode,A.OperatorsType,A.CodeId,Cmd,Addr,key1,key2,RContent from dbo.V_AreaToFeeCode_FeeCodeInfo A WITH(NOLOCK),
(
select AreaId,OperatorsType from dbo.UserInfo  WITH(NOLOCK)
where AreaId>0  and Phone!='' and IMSI!='' and MonthSumFee<800  and addflag=0  and AvailFlag=1  group by AreaId,OperatorsType having COUNT(AreaId)>10
) C ,
dbo.V_GetUsableMaxCode B WITH(NOLOCK)
where A.FeeMode=11 and A.AreaId=C.AreaId and A.OperatorsType=C.OperatorsType and A.CodeId=B.CodeID
) B  
where A.AreaId=B.AreaId and A.OperatorsType=B.OperatorsType
and 
0.00005 >= CAST(CHECKSUM(NEWID(), UserId) & 0x7fffffff AS float)/ CAST (0x7fffffff AS int)
order by UserId

--和下面语句对比
--语句2:
select top 1 A.UserId,A.Phone,B.CodeId,Cmd,Addr,key1,key2,RContent,B.FeeMode from dbo.[V_AddFeePhoneUser] A  WITH(NOLOCK),
(
select A.AreaId,A.FeeMode,A.OperatorsType,A.CodeId,Cmd,Addr,key1,key2,RContent from dbo.V_AreaToFeeCode_FeeCodeInfo A WITH(NOLOCK),
(
select AreaId,OperatorsType from dbo.UserInfo  WITH(NOLOCK)
where AreaId>0  and Phone!='' and IMSI!='' and MonthSumFee<800  and addflag=0  and AvailFlag=1  group by AreaId,OperatorsType having COUNT(AreaId)>10
) C ,
dbo.V_GetUsableMaxCode B WITH(NOLOCK)
where A.FeeMode=11 and A.AreaId=C.AreaId and A.OperatorsType=C.OperatorsType and A.CodeId=B.CodeID
) B  
where A.AreaId=B.AreaId and A.OperatorsType=B.OperatorsType
and 
0.00005 >= CAST(CHECKSUM(NEWID(), UserId) & 0x7fffffff AS float)/ CAST (0x7fffffff AS int)
--两个的性能差别在哪?原因是什么?


我在这守着,看看有没有人来。 性能 sql --------------------编程问答-------------------- 有没有人啊? 我顶!! --------------------编程问答-------------------- 我看你两条语句都一样的,就第一条语句的最后加了个排序的 --------------------编程问答-------------------- 对,两条语句的差别就是语句1使用了排序,语句2没有使用排序。 --------------------编程问答--------------------
引用 3 楼 zxjocy 的回复:
对,两条语句的差别就是语句1使用了排序,语句2没有使用排序。
那你还问性能差别,要差也就差在代码不同点 --------------------编程问答--------------------
引用 4 楼 zhurcn 的回复:
Quote: 引用 3 楼 zxjocy 的回复:

对,两条语句的差别就是语句1使用了排序,语句2没有使用排序。
那你还问性能差别,要差也就差在代码不同点

这两条语句的性能差别会有很大的,去使用查询可以看出来,语句1的性能明显比语句2的性能要高很多倍。所以想知道导致这种结果的原因是什么? --------------------编程问答-------------------- --------------------编程问答--------------------
引用 5 楼 zxjocy 的回复:
语句1的性能明显比语句2的性能要高很多倍。所以想知道导致这种结果的原因是什么?

没有你的测试环境。可你说反了吧?我觉得应该是语句1慢很多才对。
你再试下order by UserId DESC
--------------------编程问答-------------------- 根据我自己测试的结果,实际上语句1的性能会比语句2的性能要高100倍以上。具体原因就不是很清楚啊。 --------------------编程问答-------------------- SQL 语句是重右边往左执行的哦 --------------------编程问答-------------------- 这里和sql语句的执行顺序无关。 --------------------编程问答-------------------- 会不会是因为
select top 1 A.UserId 
这个引起的 --------------------编程问答-------------------- 当都不加order by时,一个使用top 1 一个不使用top 1
正常使用top 1 性能高;

但在这视图里边使用了三层复合联合查询,最后使用一个随机抽样率,抽取出一定概念的比例数,
再从里边取一条,完成随机取一行的任务

但从执行计划中可以看到不使用top 1,把所有抽样数据select出来时,性能是很高的,而且IO值就只有300多字节,也就是输出的行少

但使用了top 1后,性能差了1W多倍,输出的IO值增长到10W多字节,
这是由于随机抽样,生成了一个随机的抽样数据表,在没有生成数据前的操作,全部都是在搜引用,但最后在取出首行时,
由于所对应的数据集和物理表中的行不对应,这个时候的top 1的查询就变成了,在生成的数据集中进行seek操作,
对索引中用户表对应的userid进行索引扫描,取出首行这个过程中对索引进行了全索引seek扫描操作,IO增大,同时查询时间大增。

由于我们一定要取一行,增加TOP 1后,增加order by userid原本增加排序会造成性能下降
但些时随机抽样生成的数据很小,这时针对聚集索引字段userid进行排序,相当于重新使用索引查找,查找的范围变成是特定行,而不是seek操作这时的top 1操作才真正提高了性能。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,