【问题标题】:Stored procedure using too many selects?使用太多选择的存储过程?
【发布时间】:2017-08-04 10:34:06
【问题描述】:

我最近开始对客户的存储过程进行一些性能调整,但我碰到了这段代码,但找不到让它更有效地工作的方法。

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

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

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

非常感谢我能在这方面获得帮助。

谢谢!

【问题讨论】:

  • 您是否尝试过加入表格而不是使用存在子句?
  • 这些表中只有一列......加入不会解决它:\

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


【解决方案1】:

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

【讨论】:

  • 问题是“Fleet”表的连接是为了获取所有 FleedID 为 null 并且 companyID 与fleetID 匹配的记录。那变化呢:我把它加起来而不是加入。并且存在(从 dbo.Fleet 中选择 FleetId,其中 Fleetid = t.FleetID 和 CompanyID=@ActorCompanyID)
  • 连接插入语句中需要的表。其他不是必需的。
  • 这是错误的。如果您查看查询,您可以理解连接是用于谓词的。在测试了相同的查询但将连接排除在外并在 where 子句中使用谓词之后,我的性能变得更差。
【解决方案2】:

实际上,您应该检查几件事并查看性能差异。首先,正如前面的答案所建议的那样,您应该尽可能省略类似 count(*) 的聚合。如果表这么大,这些函数的成本会成倍增加。您甚至可以考虑将这些计数存储在具有适当索引约束的单独表中。

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

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

希望对你有帮助。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      • 2015-05-12
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      相关资源
      最近更新 更多