我所拥有的是一个查询,它获取一组数据。该查询在特定时间运行。然后,在30分钟后,我有了另一个查询(相同的语法),该查询运行并获取同一组数据。最后,我有第三个查询(正在讨论的查询),它比较两组数据。它提取的记录与以下记录一致:如果在第一个数据集中“ FEDVIP_Active
”为FALSE,在第二个数据集中为“ TRUE”,则 OR “ UniqueID
”在第一个数据集中不存在,而在第二个数据集中存在,并且FEDVIP_Active
为TRUE。我质疑下面进行比较的查询的性能。 30分钟后超时。您是否能看到我不应该做的事情才能成为最高效的跑步方法?我正在比较的两个相同的数据集每个都有大约一百万条记录。
第一个获取初始数据集的查询:
select Unique_ID, First_Name, FEDVIP_Active, Email_Primary
from Master_Subscribers_Prospects
第二个查询与第一个查询完全相同。
然后,下面的第三个查询将数据进行比较:
select
a.FEDVIP_Active,
a.Unique_ID,
a.First_Name,
a.Email_Primary
from
Master_Subscribers_Prospects_1 a
inner join
Master_Subscribers_Prospects_2 b
on 1 = 1
where a.FEDVIP_Active = 1 and b.FEDVIP_Active = 0 or
(b.Unique_ID not in (select Unique_ID from Master_Subscribers_Prospects_1) and b.FEDVIP_Active = 1)
答案 0 :(得分:1)
1 = 1
上的内部联接是伪装的交叉联接,并且交叉联接产生的行数可以快速增长。它是两个关系中的行数的乘积。为了提高性能,您希望将中间结果保持得尽可能小。
然后,当子查询的行数很大时,通常会比IN
EXISTS
的性能更好。
但是我认为您根本不需要IN
或EXITS
。
假设unique_id
标识一条记录并且不为空,则可以在常见的unique_id
上将第一个表连接到第二个表。然后,并且仅当第二个表中的unique_id
记录没有退出第一个表的unique_id
且联接结果为null时,您才可以进行检查。
SELECT b.fedvip_active,
b.unique_id,
b.first_name,
b.email_primary
FROM master_subscribers_prospects_2 b
LEFT JOIN master_subscribers_prospects_1 a
ON b.unique_id = a.unique_id
WHERE a.fedvip_active = 1
AND b.fedvip_active = 0
OR a.unique_id IS NULL
AND b.fedvip_active = 1;
对于该查询,master_subscribers_prospects_1 (unique_id, fedvip_active)
和master_subscribers_prospects_2 (unique_id, fedvip_active)
上的索引也可能有助于加快速度。
答案 1 :(得分:1)
如果我理解正确,那么您希望第二个数据集中的所有记录都处于活动状态(不存在或通过将标志设置为不活动),而第一个数据集中的对应唯一ID处于不活动状态。
我建议exists
:
select a.*
from Master_Subscribers_Prospects_1 a
where a.FEDVIP_Active = 1 and
not exists (select 1
from Master_Subscribers_Prospects_2 b
where b.Unique_ID = a.Unique_ID and
b.FEDVIP_Active = 1
);
为了提高性能,您希望在Master_Subscribers_Prospects_2(Unique_ID, FEDVIP_Active)
上建立索引。
答案 2 :(得分:0)
在sats中进行内部选择总是不好的。
以下是带有left join
的相同版本,可能对您有用。
select
a.FEDVIP_Active,
a.Unique_ID,
a.First_Name,
a.Email_Primary
from
Master_Subscribers_Prospects_1 a
inner join
Master_Subscribers_Prospects_2 b on 1 = 1
left join Master_Subscribers_Prospects_1 sa on sa.Unique_ID = b.Unique_ID
where (a.FEDVIP_Active = 1 and b.FEDVIP_Active = 0) or
(sa.Unique_ID is null and b.FEDVIP_Active = 1)