使用太多选择的存储过程?

时间:2017-03-14 07:29:36

标签: sql sql-server performance stored-procedures database-administration

我最近开始在客户端的存储过程中进行一些性能调优,并且我碰到了这一块代码,并且无法找到一种方法来提高它的工作效率。

declare @StationListCount int;
select @StationListCount = count(*) from @StationList;
declare @FleetsCnt int;
select @FleetsCnt=COUNT(*) from @FleetIds;
declare @StationCnt int;
select @StationCnt=COUNT(*) from @StationIds;
declare @VehiclesCnt int;
select @VehiclesCnt=COUNT(*) from @VehicleIds;

declare @TrIds table(VehicleId bigint,TrId bigint,InRange bit);

insert into @TrIds(VehicleId,TrId,InRange)
select t.VehicleID,t.FuelTransactionId,1
from dbo.FuelTransaction t
join dbo.Fleet f on f.FleetID = t.FleetID and f.CompanyID=@ActorCompanyID
where t.TransactionTime>=@From and (@To is null or t.TransactionTime<@To)
and (@StationListCount=0 or exists (select id fRom @StationList where t.FuelStationID = ID))
and (@FleetsCnt=0 or exists (select ID from @FleetIds where ID = t.FleetID))
and (@StationCnt=0 or exists (select ID from @StationIds where ID = t.FuelStationID))
and (@VehiclesCnt=0 or exists (select ID from @VehicleIds where ID = t.VehicleID))
and t.VehicleID is not null

insert命令会减慢整个过程并占用99%的资源。

I am not sure but i think these nested loops are referring to the queries inside the where clause

我非常感谢能得到的帮助。

谢谢!

3 个答案:

答案 0 :(得分:0)

插入只使用1个表作为车辆ID,因此不需要连接其他表。

答案 1 :(得分:0)

实际应该检查一些事情,看看性能差异。首先,正如之前的回答建议你应该省略计数(*) - 尽可能多地加重。如果表格如此之大,这些函数的成本会呈指数级增长。您甚至可以考虑将这些计数存储在具有适当索引约束的单独表中。

我还建议你将select语句拆分成多个语句,因为当你使用那么多的NULL检查,或者组合条件时;您的索引可能被绕过,因此您的查询成本会增加很多。有时,使用UNION可能会提供比使用此类条件更好的性能。

实际上,您应该尝试所有这些,看看哪些适合您的需求

希望它有所帮助。

答案 2 :(得分:0)

我没有看到@table变量的声明,但是(假设其中的ID是唯一的)考虑将此信息传递给优化器,IOW向它们添加主键约束。

另外,将option(recompile)添加到查询的末尾。