如何提高这个SQL语句的效率?

时间:2014-11-03 02:49:53

标签: sql sql-server-2008 tsql subquery

我在SQL上非常平均 - 无论如何都不是最好的。我有以下SQL语句,我理解可能并没有考虑到性能:

select 
    COI1.EmailAddress, 
    COI1.DateTriggered as 'COIEmail1Date', 
    COI2.DateTriggered as 'COIEmail2Date' 
from 
    COITOUCH1_DE COI1
left join 
    COITOUCH2_DE COI2 on COI1.EmailAddress = COI2. EmailAddress 
where 
    COI1.EmailAddress not in (select EmailAddress from _Subscribers) 
    or COI2.EmailAddress not in (select EmailAddress from _Subscribers)

简而言之,我需要一个记录列表,这些记录位于_Subscribers表中表COITOUCH1_DE OR COITOUCH2_DE中。这个问题需要永远 - 我怎样才能提高效率呢?

3 个答案:

答案 0 :(得分:3)

对不起我的第一个回答。我以为你说两个COI表必须有电子邮件地址。

如果您希望COI表的EITHER具有电子邮件地址(但不是_Subscribers),为什么不使用UNION呢?像这样:

SELECT DISTINCT coi.email, coi.date 
FROM ((select EmailAddress as email, DateTriggered as date from COITOUCH1_DE)
    UNION
    (select EmailAddress as email, DateTriggered as date from COITOUCH2_DE)
    ) AS coi
    LEFT JOIN _Subscribers AS sub ON coi.EmailAddress = sub.EmailAddress
WHERE sub.EmailAddress IS NULL;

原始答案(认为您的意思是COI1和COI2必须有电子邮件地址):

你的not in条款正在杀死你。尝试双连接并检查null。

select COI1.EmailAddress, 
    COI1.DateTriggered as 'COIEmail1Date', 
    COI2.DateTriggered as 'COIEmail2Date' 
from COITOUCH1_DE COI1
    inner join COITOUCH2_DE COI2 on COI1.EmailAddress = COI2.EmailAddress
    left join _Subscribers SUB on COI1.EmailAddress = SUB.EmailAddress
where SUB.EmailAddress IS NULL;

你希望你的第一个连接是一个内连接(因为你说它必须存在于前两个表的两个中),你第二个连接是一个左连接,这样你就可以看到是否没有相应的记录_Subscribers表。

答案 1 :(得分:1)

这是SQL语句:

select COI1.EmailAddress, COI1.DateTriggered as COIEmail1Date, 
       COI2.DateTriggered as COIEmail2Date
from COITOUCH1_DE COI1 left join
     COITOUCH2_DE COI2
     on COI1.EmailAddress = COI2.EmailAddress 
where COI1.EmailAddress not in (select EmailAddress from _Subscribers) or 
      COI2.EmailAddress not in (select EmailAddress from _Subscribers);

建议:不要使用单引号作为列别名。单引号只能用于字符串和日期常量。

您可以简化查询,因为COI2.EmailAddressCOI1.EmailAddress相同:

select COI1.EmailAddress, COI1.DateTriggered as COIEmail1Date, 
       COI2.DateTriggered as COIEmail2Date
from COITOUCH1_DE COI1 left join
     COITOUCH2_DE COI2
     on COI1.EmailAddress = COI2.EmailAddress 
where COI1.EmailAddress not in (select EmailAddress from _Subscribers);

对于查询,它将受益于索引。我建议:_Subscribers(EmailAddress)COITOUCH2_DE(EmailAddress)

答案 2 :(得分:1)

这是一个我认为实际上会为您提供所需结果的查询。

select 
    COI1.EmailAddress, 
    COI1.DateTriggered as 'COIEmail1Date', 
    COI2.DateTriggered as 'COIEmail2Date' 
from COITOUCH1_DE COI1
full outer join COITOUCH2_DE COI2 on COI1.EmailAddress = COI2.EmailAddress 
where isnull(COI1.EmailAddress, COI2.EmailAddress)
      not in (select EmailAddress from _Subscribers)

您应该查看执行计划(查询 - >在SQL Server Management Studio中包含实际执行计划)以查看可能存在的问题。您可能只需要一两个索引。

相关问题