除了加入之外,还有其他更快捷的方法来进行更新吗?这是我的查询,但它有点慢:
UPDATE @user_dupes
SET ExternalEmail = ud2.Email
FROM @user_dupes ud1
INNER JOIN(
SELECT Email, UserName
FROM @user_flat_emailtable_dupes
WHERE EmailType = 2
AND Email IS NOT NULL AND LEN(Email) > 0
) ud2
ON ud1.UserName = ud2.UserName
感谢您的任何想法
答案 0 :(得分:4)
如果您使用的是SQL Server,那么您几乎就在那里。这只是一个小问题:
UPDATE ud1 --little fix here!
SET ExternalEmail = ud2.Email
FROM @user_dupes ud1
INNER JOIN
(
SELECT Email, UserName
FROM @user_flat_emailtable_dupes
WHERE EmailType = 2
AND Email IS NOT NULL AND LEN(Email) > 0
) ud2
ON ud1.UserName = ud2.UserName
答案 1 :(得分:4)
在@Adrian所说的基础上进行了一些改变......
UPDATE
ud1 -- @Adrian's change. Update the instance that you have already aliased.
SET
externalEmail = ud2.Email
FROM
@user_dupes AS ud1
INNER JOIN
@user_flat_emailtable_dupes AS ud2
ON ud1.UserName = ud2.UserName
WHERE
ud2.EmailType = 2 -- Removed sub-query, for layout, doubt it will help performance
AND ud2.Email IS NOT NULL
AND ud2.Email <> '' -- Removed the `LEN()` function
但最重要的过去可能是确保你有索引。 JOIN
对于此逻辑(或相关的子查询等)是必需的,因此您希望连接具有高效性。
@user_dupes上的(UserName)索引,以及@user_flat_emailtable_dupes上的(EmailType,Email,UserName)索引。 (假设ud2是过滤后的较小的表)
使用指定的索引,从LEN(Email) > 0
到Email <> ''
的更改可能允许索引搜索而不是扫描。你的桌子越大,这就越明显。
答案 2 :(得分:1)
我相信这个查询会做同样的事情(尽管你必须确保形成没有重复用户名的@user_flat_emailtable_dupes)。我没有检查他们是否有不同的执行计划。看起来你正在提炼垃圾输入,我提到这部分是因为我做了很多,并且发现MERGE很有用(因为我不知道UPDATE FROM如何工作所以对我来说更有用)。部分是因为我从未使用MERGE和变量。似乎至少目标表必须是别名,或者解析器决定@ ud1是标量变量并且它会中断。
MERGE @user_dupes AS ud1
USING @user_flat_emailtable_dupes AS ud2
ON emailType = 2
AND COALESCE(ud2.email, '') <> ''
AND ud2.username = ud1.username
WHEN MATCHED THEN UPDATE
SET externalEmail = ud2.email
;