Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何提高此SQL语句的效率?_Sql_Sql Server 2008_Tsql_Subquery - Fatal编程技术网

如何提高此SQL语句的效率?

如何提高此SQL语句的效率?,sql,sql-server-2008,tsql,subquery,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.EmailAd

我在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)

简而言之,我需要一个表COITUCH1\u DE或COITUCH2\u DE中的记录列表,这些记录不在_Subscribers表中。此查询需要花费很长时间-如何提高效率?

以下是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.EmailAddress与COI1.EmailAddress相同:


至于查询,它将受益于索引。我建议:_SubscribersEmailAddress和COITOUCH2_DEEmailAddress。

很抱歉我的第一个答案。我记得你说过两个COI表都必须有电子邮件地址

如果您希望其中一个COI表具有电子邮件地址,但不具有订阅者,为什么不使用联合呢?大概是这样的:

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必须具有电子邮件地址:

你的不在条款正在害死你。尝试双连接并检查是否为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表中是否没有相应的记录。

我想这是一个查询,它实际上会得到你想要的结果

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)

您应该在SQLServerManagementStudio中查看执行计划查询->包含实际执行计划,以了解可能存在的问题。您可能只需要一两个索引。

如果您想要两个表中都存在的记录,首先将其更改为内部联接。@Blorgbeard对不起,我是说OROk,那么您实际上需要一个完整的外部联接。目前只在COI2中的行不会被报告。至于优化,我建议您查看您的执行计划查询->在SSMS中包含实际执行计划,以获得一些提示。感谢您的回答。。不使用联盟的原因是因为我不希望重复的电子邮件地址。。。例如,如果COITOUCH1\u DE和COITOUCH2\u DE都有一个电子邮件地址,则会有两个单独的记录,其中COI1.DateTrigger有一个值,另一个为空,然后重复的电子邮件地址将正好相反-COI2.DateTrigger将有一个值,而COI1.DateTrigger将为空。我可能有误解,但UNION不会将您的记录放在一起。如果COI1有2条记录:a@a.com, 1/1/2011 b@b.com,2012年2月2日,COI2有2项记录:a@a.com, 1/1/2011 c@c.com,2013年3月3日,则工会将有4条记录,其中有两列,且所有值均不为空:a@a.com, 1/1/2011 b@b.com, 2/2/2012 a@a.com, 1/1/2011 c@c.com,2013年3月3日我在SELECT上添加了一个DISTINCT,以消除join/where后重复的a。当然,如果a@a.com在两个不同的表中有两个不同的日期,DISTINCT将同时保留这两个日期。我想你会想要的。我的结果集应该包括EmailAddress、COIEmail1Date和COIEmail2Date。COIEmail1Date和COIEmail2Date将同时填充,或者其中一个为空。当前,您的语句只返回一个日期列,而不是两个。。。
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)