首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

这个“存储过程”应当怎样优化

2012-07-03 
这个“存储过程”应该怎样优化这个“存储过程”应该怎样优化???执行时间为“20秒”,目标要控制在“5秒”以内,表(Wa

这个“存储过程”应该怎样优化
这个“存储过程”应该怎样优化???
执行时间为“20秒”,目标要控制在“5秒”以内,表(WarnUseEnergy)中的数据量有“200多万”。


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER proc [dbo].[NSP_GetWarnTop10]
@MeterType char(4)
as

select top 10 COUNT(wue.MeterNo) as num,(m.MeterName+'('+RTRIM(wue.MeterNo)+')') as MeterNN,(r.RegionName+' '+(ISNULL(b.BuildingName,''))) as RegionBuilding from WarnUseEnergy wue left join Meter m on wue.MeterNo=m.MeterNo left join BuildingMeterRef bmr on wue.MeterNo=bmr.MeterNo left join Building b on bmr.BuildingNo=b.BuildingName left join RegionMeterRef rmr on wue.MeterNo=rmr.MeterNo left join Region r on rmr.RegionNo=r.RegionNo where wue.MeterType=@MeterType group by wue.MeterNo,m.MeterName,b.BuildingName,r.RegionName order by num desc

应该怎样优化,减少运算。。。

[解决办法]

SQL code
select top 10 COUNT(wue.MeterNo) as num,(m.MeterName+'('+RTRIM(wue.MeterNo)+')') as MeterNN,(r.RegionName+' '+(ISNULL(b.BuildingName,''))) as RegionBuilding from WarnUseEnergy wue left join Meter m on wue.MeterNo=m.MeterNo left join BuildingMeterRef bmr on wue.MeterNo=bmr.MeterNo left join Building b on bmr.BuildingNo=b.BuildingName left join RegionMeterRef rmr on wue.MeterNo=rmr.MeterNo left join Region r on rmr.RegionNo=r.RegionNo where wue.MeterType=@MeterType group by wue.MeterNo,m.MeterName,b.BuildingName,r.RegionName order by num desc--这么多left join ,用临时表或者试图吧从你的语句上来说算法一点都不复杂
[解决办法]
你这几个表,每个表大约有多少数据?

正常索引建好了200万数据1秒内是可以搞定的。

但是如果是多表连接查询就不同了,要看各表的数据量,和条件字段的索引等情况。
[解决办法]
儘量使用INNER JOIN 
在 WarnUseEnergy表上 建立複合索引 , (MeterNo,MeterType) 按這個順序.
SQL code
CREATE NONCLUSTERED INDEX WarnUseEnergy_MeterNo_MeterType ON WarnUseEnergy(MeterNo,MeterType)
[解决办法]
儘量使用INNER JOIN 
在 WarnUseEnergy表上 建立複合索引 , (MeterNo,MeterType) 按這個順序.
SQL code
CREATE NONCLUSTERED INDEX WarnUseEnergy_MeterNo_MeterType ON WarnUseEnergy(MeterNo,MeterType)
[解决办法]
Inner Join 只會保留相匹配的數據 
Left Join 會保留左表完整的數據
同理Right Join 會保留右表完整的數據

使用Left Join,這樣你WarnUseEnergy某些匹配不上的數據也會保留在結果裏面,導致執行速度過慢.
[解决办法]
SQL code
select top 10  COUNT(wue.MeterNo) as num,(m.MeterName+'('+RTRIM(wue.MeterNo)+')') as MeterNN,(r.RegionName+' '+(ISNULL(b.BuildingName,''))) as RegionBuilding  from [color=#FF0000](select * from WarnUseEnergy where wue.MeterType=@MeterType ) [/color]wue  left join Meter m  on wue.MeterNo=m.MeterNo  left join BuildingMeterRef bmr  on wue.MeterNo=bmr.MeterNo  left join Building b  on bmr.BuildingNo=b.BuildingName  left join RegionMeterRef rmr  on wue.MeterNo=rmr.MeterNo  left join Region r  on rmr.RegionNo=r.RegionNo    group by wue.MeterNo,m.MeterName,b.BuildingName,r.RegionName  order by num desc
[解决办法]
题外话:最后一句‘order by num desc’是错的吧
[解决办法]
提高效率的一般做法是用空间换时间
你把你要提取表的数据,都放到临时表里面,也就是MeterType=@MeterType 的时候的MeterNo都符合的数据,然后再把临时表left join。
这样子临时表的数据会少很多,left join的时候速度也会快很多
[解决办法]
临时表一方面数据量少,另一方面是你独占的,所以查询速度会很快
我曾经做过一个存储过程执行要2小时,用临时表后只需要半小时

热点排行