一条sql语句,求大神指导优化下

geniuswjt 2011-11-15 03:34:02
加精

--以下代码16秒,查两次union的方式
select a.spid,a.notes,a.progtype,a.feevalue/100 as feevalue,b.mt_content,b.id ,num1,num2 from (
select spid,mtype,num1=isnull(count(distinct mobile),0) from v_mr
where createtime>='2011-11'+'-01' and stat='DELIVRD'
group by spid,mtype) m
join (
select spid,mtype,num2=isnull(count(distinct mobile),0) from v_mr
where createtime>='2011-10'+'-01' and stat='DELIVRD'
group by spid,mtype
) n on (m.spid=n.spid and m.mtype=n.mtype)
join esms_limit a on (a.spid=m.spid and a.type=m.mtype)
join esms_spinfo b on (a.spid=b.spid)

--以下代码将近3分钟,为了可读性
select a.spid,a.notes,a.progtype,a.feevalue/100 as feevalue,b.mt_content,b.id ,num1,num2 from (
select spid,mtype,
num1=isnull(count(distinct case when createtime>='2011-11'+'-01' and stat='DELIVRD' then mobile end),0),
num2=isnull(count(distinct case when createtime>='2011-10'+'-01' and stat='DELIVRD' then mobile end),0)
from v_mr
group by spid,mtype
) m
join esms_limit a on (a.spid=m.spid and a.type=m.mtype)
join esms_spinfo b on (a.spid=b.spid)

简单说下需求:就是查最近1个月的数据和最近2个月的数据,再和2个配置表连接。
索引spid啊,createtime啊,stat啊之类的上面该建的都建了。
主要是想一条语句让页面显示出来这些数据,这个速度还是等不急。
太长不好看,又不太想用存储过程,不知道还有什么地方可以优化不,求大神指教

...全文
10038 187 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
187 条回复
切换为时间正序
请发表友善的回复…
发表回复
iLugo 2011-11-28
  • 打赏
  • 举报
回复
太多了,看不下去,如果有表的话可能更有逻辑些...
xiao_hn 2011-11-28
  • 打赏
  • 举报
回复
楼主,先贴出每个表的表结构,表索引组成,表数据量,再来进行下一步吧。
mmcgzs 2011-11-28
  • 打赏
  • 举报
回复
终极优化还是需要临时表或者做job保存到单独的表
稻庄 2011-11-26
  • 打赏
  • 举报
回复
就将就下存储过程呗
放大师傅 2011-11-26
  • 打赏
  • 举报
回复
sorry,刚才发错了信息 。
放大师傅 2011-11-26
  • 打赏
  • 举报
回复
zjh_c_s_d_n 2011-11-26
  • 打赏
  • 举报
回复
看高人优化
jfjjh 2011-11-25
  • 打赏
  • 举报
回复
人才写嘿嘿
MLGB_HOHO 2011-11-25
  • 打赏
  • 举报
回复
试下这个:我觉得在查询大量数据的同时又有计算 所以减慢了速度。


select
spid,notes,progtype, feevalue,mt_content,id ,
num1=isnull(count(distinct case when createtime>='2011-11'+'-01' and stat='DELIVRD' then mobile end),0),
num2=isnull(count(distinct case when createtime>='2011-10'+'-01' and stat='DELIVRD' then mobile end),0)
(
select a.spid,a.notes,a.progtype,a.feevalue/100 as feevalue,b.mt_content,b.id ,mobile from (
select spid,mtype
from v_mr where createtime>='2011-11'+'-01' and stat='DELIVRD'
group by spid,mtype
) m
join esms_limit a on (a.spid=m.spid and a.type=m.mtype)
join esms_spinfo b on (a.spid=b.spid)
)

simu1123 2011-11-24
  • 打赏
  • 举报
回复
不错。。。。。。。。。。。。


leftgo86 2011-11-24
  • 打赏
  • 举报
回复
我也是来观摩的 学习学习
fhy1024 2011-11-24
  • 打赏
  • 举报
回复
如果查询很费事,那么考虑下 数据表结构的优化。。查询嵌套子查询确实。。性能不高~~
titian2046 2011-11-24
  • 打赏
  • 举报
回复
方法1走了索引, union all取的是两次时间索引的数据。
方法2 取了全表的数据,所以会慢,加上时间限制条件以后还慢,是因为方法1每次只需要保存1个distinct的集合,方法二还需对每条记录做额外的case when判断,而且还需要同时保持两个distinct的记录集。假设记录数两个月差不多的话。方法1只对两个60w的集合各做1次distinct,方法2则对 60w+60w0的集合各做1次distinct,速度是有差别的。

结论是 union all已经是较优化的操作,不必苛求代码简短,其实代码简短也不等于可读性强。


q965747199 2011-11-24
  • 打赏
  • 举报
回复
我啥也看不懂,是不是该回幼儿园补习了?
lyroot 2011-11-23
  • 打赏
  • 举报
回复
我靠,这个还可以这样写... 汗.. 受教.
SYBN 2011-11-22
  • 打赏
  • 举报
回复
围观~华丽丽的表示看不懂~
jacquesgw 2011-11-22
  • 打赏
  • 举报
回复
楼主加油
grart 2011-11-22
  • 打赏
  • 举报
回复

上面的是在
WHERE CREATETIME>='2011-11'+'-01'和
WHERE CREATETIME>='2011-10'+'-01'中的记录去查数据,
下面的是整表查数据,当然要比上面的慢。你下面的加一句
WHERE CREATETIME>='2011-10'+'-01'试试

select a.spid,a.notes,a.progtype,a.feevalue/100 as feevalue,b.mt_content,b.id ,num1,num2 from (
select spid,mtype,
num1=isnull(count(distinct case when createtime>='2011-11'+'-01' and stat='DELIVRD' then mobile end),0),
num2=isnull(count(distinct case when createtime>='2011-10'+'-01' and stat='DELIVRD' then mobile end),0)
from v_mr
WHERE CREATETIME>='2011-10'+'-01'
group by spid,mtype
) m
join esms_limit a on (a.spid=m.spid and a.type=m.mtype)
join esms_spinfo b on (a.spid=b.spid)
liuyashao66 2011-11-21
  • 打赏
  • 举报
回复
搂主能不能把执行计划贴出来呀?
cmmrpp 2011-11-21
  • 打赏
  • 举报
回复
代码太长了,看不懂
加载更多回复(118)

34,838

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧