这个“存储过程”应该怎样优化
这个“存储过程”应该怎样优化???
执行时间为“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
应该怎样优化,减少运算。。。
[解决办法]
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) 按這個順序.
CREATE NONCLUSTERED INDEX WarnUseEnergy_MeterNo_MeterType ON WarnUseEnergy(MeterNo,MeterType)
[解决办法]
儘量使用INNER JOIN
在 WarnUseEnergy表上 建立複合索引 , (MeterNo,MeterType) 按這個順序.
CREATE NONCLUSTERED INDEX WarnUseEnergy_MeterNo_MeterType ON WarnUseEnergy(MeterNo,MeterType)
[解决办法]
Inner Join 只會保留相匹配的數據
Left Join 會保留左表完整的數據
同理Right Join 會保留右表完整的數據
使用Left Join,這樣你WarnUseEnergy某些匹配不上的數據也會保留在結果裏面,導致執行速度過慢.
[解决办法]
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小时,用临时表后只需要半小时