我的查询存在性能问题。
第一个表是一个Customer表,其中包含数百万条记录。客户表有一列电子邮件地址和一些其他有关客户的信息。
第二个表是一个CommunicationInfo表,它只包含电子邮件地址。
我想要的是这里; CommunicationInfo表中的电子邮件地址在Customers表中重复的次数。什么是表现最好的查询。
我可以解释这种情况的基本查询是;
Select ci.Email, count(*) from Customer c left join
CommunicationInfo ci on c.Email1 = ci.Email or c.Email2 = ci.Email
Group by ci.Email
但可以肯定的是,执行大约需要5,6分钟。
先谢谢。
答案 0 :(得分:3)
如果您在Customer.Email上有索引,而另一个在CommunicationInfo.Email
上有索引,那么这个查询就好了。Select
c.Email, count(*)
from Customer c
left join CommunicationInfo ci on c.Email1 = ci.Email
left join CommunicationInfo ci2 on c.Email2 = ci2.Email
Group by c.Email
答案 1 :(得分:1)
使用OR
条件会剥夺优化机会使用HASH JOIN
或MERGE JOIN
。
使用此:
SELECT ci.Email, SUM(cnt)
FROM (
SELECT ci.Email, COUNT(c.Email) AS cnt
FROM CommunicationInfo ci
LEFT JOIN
Customer c
ON c.Email1 = ci.Email
GROUP BY
ci.Email
UNION ALL
SELECT ci.Email, COUNT(c.Email) AS cnt
FROM CommunicationInfo ci
LEFT JOIN
Customer c
ON c.Email2 = ci.Email
GROUP BY
ci.Email
) q2
GROUP BY
ci.Email
或者这个:
SELECT ci.Email, COUNT(*)
FROM CommunicationInfo ci
LEFT JOIN
(
SELECT Email1 AS email
FROM Customer c
UNION ALL
SELECT Email2
FROM Customer
) q
ON q.Email = ci.Email
GROUP BY
ci.Email
确保您在Customer(Email)
和Customer(Email2)
如果您的电子邮件大部分未填写,第一个查询将更有效,第二个查询 - 如果大多数电子邮件已填满,则会更有效。
答案 2 :(得分:1)
你提到:
我想要的是这里;多少 倍于电子邮件地址 CommunicationInfo表重复 客户表。可能是什么 表演者最多的查询。
对我来说,听起来你可以很容易地使用INNER JOIN - 这很可能会快得多,因为它会将搜索范围限制在那些真正拥有电子邮件的客户身上 - 任何人都不会根本没有电子邮件(因此计数(*)= 0)甚至不会被看到 - 即使只是SQL Server必须计算和分组的行数,这可能会产生很大的不同。
所以试试这个:
SELECT
ci.Email, COUNT(*)
FROM
dbo.Customer c
INNER JOIN dbo.CommunicationInfo ci
ON c.Email1 = ci.Email OR c.Email2 = ci.Email
GROUP BY
ci.Email
在你的情况下如何表现?
答案 3 :(得分:0)
根据您的环境,您可能无法对此进行优化。
几个问题:
建议: