我有一个桌子的野兽,在外部查询中有超过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上有一个聚簇索引,它们是不同的列。
任何人都可以建议改善此查询和运行时间的最佳方法。
答案 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