0

我最近开始在客户端的存储过程中进行一些性能调整,并且碰到了这段代码,无法找到一种更有效的工作方式。使用太多选择的存储过程?

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 [email protected] 
where t.TransactionTime>[email protected] 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

我非常感谢帮助我能得到这个。

谢谢!

+0

你有没有尝试加入表而不是使用exists子句? – Sharad

+0

这些表在它们中只有一列....加入不会解决它:\ –

回答

0

插入仅使用1个车辆ID表,因此加入其他表不需要。

+0

问题是,“Fleet”表的连接是将所有FleedID为空的记录与companyID匹配fleetID。那个改变呢:我加了它而不是加入。 \t 并存在(从dbo.Fleet中选择FleetId,其中Fleetid = t.FleetID和CompanyID = @ ActorCompanyID) –

+1

您的1)显然是错误的。 – dean

+0

感谢Dean的纠正。 –

0

有几件事情,你实际上应该去看看性能的差异。首先,正如前面的回答建议你应该尽可能省略count(*) - 就像加重词一样。如果桌子太大,这些功能的成本会成倍增加。您甚至可以考虑将这些计数存储在具有适当索引约束的独立表中。

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

其实,你应该尝试所有这些,看看有什么适合您的需要

希望它帮助。

0

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

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