最佳设计策略排除大数据集-T-SQL

时间:2018-12-07 13:55:59

标签: sql-server tsql sql-server-2012

我不确定是否应该在这里或数据库管理员那里询问。因为是设计,所以我想在这里。

我有一张发票表(7400万行),该表有30列以上。列之一是电子邮件地址。与其构建必须更新的电子邮件表,不如使用一种类似视图的方法从“实时”收集发票中的电子邮件地址。

还有另一个包含退信的电子邮件回复表。我的目标是让流程(可能是视图)从响应表中没有退回电子邮件记录的发票中收集所有电子邮件。

查询将类似于:

Select IndividualId, EmailAddress
From Invoices

Exclude

Select EmailAddress
From EmailResponses
Where Response = 'Bounce'

考虑到我需要使用PersonalId,排除方法可能不起作用,我尚未对此进行研究。如果是这样,我可以使用“不参加”或“加入”来完成同一件事。

这将需要大量时间和资源来运行,我正在寻找优化方法。我更关心运行时间而不是资源,因为我们的服务器上有很多可用资源,但是我可以做的任何减少资源消耗的事情都是好事。

我已经开始研究列存储索引,但是我感觉可能不是最好的方法。发票表可用于许多其他用途。

值得注意的是,这是一个“存档”表,每天从客户销售点获取更新的记录。它不是真正的OLTP数据库。目前,我们没有追求数据仓库解决方案的要求。

我可以轻松地完成所有研究并制定解决方案。我希望从社区中获得一些提示,以避免死胡同的想法和麻烦。

我们正在使用SQL Server 2012。

非常感谢任何输入。

3 个答案:

答案 0 :(得分:2)

您最好的性能选择可能是使用WHERE NOT EXISTS的相关子查询。

SELECT
  i.IndividualId
 ,i.EmailAddress
FROM
  Invoices AS i
WHERE
  NOT EXISTS
  (
    SELECT
      1
    FROM
      EmailResponses AS r
    WHERE
      r.EmailAddress = i.EmailAddress
      AND Response = 'Bounce'
  );

您怀疑,Invoices.EmailAddress上的索引会有所帮助,但它可能是旧的NONCLUSTERED INDEX。真的不需要在那里花哨。

还有其他选择,但是所有人都说过并做到这一点是一个非常可靠的实现。

在这里深入了解article on exactly this question by Aaron Bertrand

答案 1 :(得分:0)

您可以执行外部联接,然后在不存在联接记录的地方进行过滤。

SELECT i.IndividualId, i.EmailAddress
FROM Invoices i left outer join EmailResponses r on i.EmailAddress = r.EmailAddress and r.Response = 'Bounce'
WHERE r.EmailAddress IS NULL

您还应该在EmailResponses的电子邮件地址响应列上包括一个索引。

CREATE NONCLUSTERED INDEX [IX_EmailResponses_EmailAddress_Response] ON [EmailResponses] (EmailAddress ASC, Response ASC)

您还可以将索引添加到Invoices

CREATE NONCLUSTERED INDEX [IX_Invoices_EmailAddress] ON Invoices (EmailAddress ASC) INCLUDE (IndividualId)

这两个索引应该为您提供上述查询的最佳查询计划。

答案 2 :(得分:0)

您的EmailResponses表是否有一个PersonalId?

Declare @Invoices Table
(
IndividualId Int,
EmailAddress VarChar(150)
)
Insert Into @Invoices Values
(1,'em1@domain.com'),
(1,'em2@domain.com'),
(2,'em99@domain.com')

Declare @EmailResponses Table
(
IndividualId Int,
EmailAddress VarChar(150),
Response VarChar(25)
)
Insert Into @EmailResponses Values
(1,'em1@domain.com','Bounce')


Select 
   IndividualId, 
   EmailAddress
From @Invoices

Except

Select 
   IndividualId, 
   EmailAddress
From @EmailResponses
Where 
   Response = 'Bounce'