尽管返回了小的结果,但野兽表的运行时间太长

时间:2017-03-14 17:07:51

标签: sql sql-server

我有一个桌子的野兽,在外部查询中有超过4000万行。我正在做一个增量/增量负载仅仅6天的数据,但这个查询出于某种奇怪的原因需要超过25分钟,尽管它只带来了6天的数据。查询如下:

        SELECT
        ActivityId,
        ActivityPartyId,
        ISNULL(AddressUsed,'*Unknown*') As AddressUsed,
        isnull(Cast(IsPartyDeleted As INT),-9) As IsPartyDeleted,
        Isnull(ParticipationTypeMask,-9) as ParticipationTypeMask,
        PartyId,
        ISNULL(PartyIdName,'*Unknown*') As PartyIdName,
        Isnull(PartyObjectTypeCode,0) as PartyObjectTypeCode
        from ActivityPartyBase


        INNER JOIN 
        (
        SELECT activityid AS apid
        from ActivityPointerBase

        WHERE
        CreatedOn BETWEEN   DATEADD(dd, DATEDIFF(dd,2,getdate()), 0) AND  DATEADD(dd, DATEDIFF(dd,0,getdate()), 0)

         or

        ModifiedOn BETWEEN   DATEADD(dd, DATEDIFF(dd,6,getdate()), 0) AND  DATEADD(dd, DATEDIFF(dd,0,getdate()), 0)


        ) sub
        ON   ActivityId = sub.apid

子查询返回的结果只有80,000行,与从内部表返回的内部联接相比,这个行相当小。

我想知道是否有办法提高此查询的性能或在其中一列中创建索引。 activityPointerBase表在activityId上有一个聚簇索引,但ActivityParty表在ActivityPartyId上有一个聚簇索引,它们是不同的列。

任何人都可以建议改善此查询和运行时间的最佳方法。

2 个答案:

答案 0 :(得分:0)

使用Paste The Plan @ brentozar.com分享您的执行计划以下是说明:How to Use Paste the Plan

如果这些是基表而不是视图,则应检查现有索引并测试以查看是否可以从添加任何这些索引中受益:

create nonclustered index ix_ActivityPointerBase_CreatedOn_inc_ActivityId
  on dbo.ActivityPointerBase(CreatedOn)
    include (ActivityId);

create nonclustered index ix_ActivityPointerBase_ModifiedOn_inc_ActivityId
  on dbo.ActivityPointerBase(ModifiedOn)
    include (ActivityId);

create nonclustered index ix_ActivityPartyBase_ActivityId_Cover
  on dbo.ActivityPartyBase(ActivityId)
    include (
        ActivityPartyId
      , AddressUsed
      , IsPartyDeleted
      , ParticipationTypeMask
      , PartyId
      , PartyIdName
      , PartyObjectTypeCode
     );

如果ModifiedOn不可为空并且在创建时等于CreatedOn,那么您可以跳过where子句的那一部分。

select 
    ActivityId
  , ActivityPartyId
  , isnull(AddressUsed, '*Unknown*') as AddressUsed
  , isnull(cast(IsPartyDeleted as int), - 9) as IsPartyDeleted
  , isnull(ParticipationTypeMask, - 9) as ParticipationTypeMask
  , PartyId
  , isnull(PartyIdName, '*Unknown*') as PartyIdName
  , isnull(PartyObjectTypeCode, 0) as PartyObjectTypeCode
from ActivityPartyBase
inner join (
   select activityid as apid
   from ActivityPointerBase
   where 
       --CreatedOn between dateaday(day, datediff(day, 2, getdate()), 0) and dateaday(day, datediff(day, 0, getdate()), 0) 
   --or 
   ModifiedOn between dateaday(day, datediff(day, 6, getdate()), 0) and dateaday(day, datediff(day, 0, getdate()), 0)
  ) sub
    on ActivityId = sub.apid

答案 1 :(得分:0)

#Temp Tables中没有任何耻辱,特别是当你可以利用统计数据和索引时。

SELECT activityid AS apid
 INTO  #TempID
 FROM  ActivityPointerBase
 WHERE CreatedOn BETWEEN   DATEADD(dd, DATEDIFF(dd,2,getdate()), 0) AND  DATEADD(dd, DATEDIFF(dd,0,getdate()), 0)
    or ModifiedOn BETWEEN  DATEADD(dd, DATEDIFF(dd,6,getdate()), 0) AND  DATEADD(dd, DATEDIFF(dd,0,getdate()), 0)
 ORDER BY activityid

Create Index idx on #TempID (apid)


SELECT ActivityId,
       ActivityPartyId,
       ISNULL(AddressUsed,'*Unknown*') As AddressUsed,
       isnull(Cast(IsPartyDeleted As INT),-9) As IsPartyDeleted,
       Isnull(ParticipationTypeMask,-9) as ParticipationTypeMask,
       PartyId,
       ISNULL(PartyIdName,'*Unknown*') As PartyIdName,
       Isnull(PartyObjectTypeCode,0) as PartyObjectTypeCode
FROM   ActivityPartyBase A
JOIN   #TempID B on A.ActivityId = B.apid