我不确定是否应该在这里或数据库管理员那里询问。因为是设计,所以我想在这里。
我有一张发票表(7400万行),该表有30列以上。列之一是电子邮件地址。与其构建必须更新的电子邮件表,不如使用一种类似视图的方法从“实时”收集发票中的电子邮件地址。
还有另一个包含退信的电子邮件回复表。我的目标是让流程(可能是视图)从响应表中没有退回电子邮件记录的发票中收集所有电子邮件。
查询将类似于:
Select IndividualId, EmailAddress
From Invoices
Exclude
Select EmailAddress
From EmailResponses
Where Response = 'Bounce'
考虑到我需要使用PersonalId,排除方法可能不起作用,我尚未对此进行研究。如果是这样,我可以使用“不参加”或“加入”来完成同一件事。
这将需要大量时间和资源来运行,我正在寻找优化方法。我更关心运行时间而不是资源,因为我们的服务器上有很多可用资源,但是我可以做的任何减少资源消耗的事情都是好事。
我已经开始研究列存储索引,但是我感觉可能不是最好的方法。发票表可用于许多其他用途。
值得注意的是,这是一个“存档”表,每天从客户销售点获取更新的记录。它不是真正的OLTP数据库。目前,我们没有追求数据仓库解决方案的要求。
我可以轻松地完成所有研究并制定解决方案。我希望从社区中获得一些提示,以避免死胡同的想法和麻烦。
我们正在使用SQL Server 2012。
非常感谢任何输入。
答案 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
。真的不需要在那里花哨。
还有其他选择,但是所有人都说过并做到这一点是一个非常可靠的实现。
答案 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'