使用SQL比较两组数据的最佳方法

时间:2019-04-05 22:31:03

标签: sql sql-server tsql

我所拥有的是一个查询,它获取一组数据。该查询在特定时间运行。然后,在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)

3 个答案:

答案 0 :(得分:1)

1 = 1上的内部联接是伪装的交叉联接,并且交叉联接产生的行数可以快速增长。它是两个关系中的行数的乘积。为了提高性能,您希望将中间结果保持得尽可能小。

然后,当子查询的行数很大时,通常会比IN EXISTS的性能更好。

但是我认为您根本不需要INEXITS

假设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)