【发布时间】:2013-05-30 20:12:42
【问题描述】:
我继承了一个 SQL Server 2008 R2 项目,其中包括从另一个表更新表:
-
Table1(大约 150,000 行)有 3 个电话号码字段(Tel1,Tel2,Tel3) -
Table2(大约有 20,000 行)有 3 个电话号码字段(Phone1,Phone2,Phone3)
.. 当这些数字中的任何一个匹配时,Table1 应该被更新。
当前代码如下:
UPDATE t1
SET surname = t2.surname, Address1=t2.Address1, DOB=t2.DOB, Tel1=t2.Phone1, Tel2=t2.Phone2, Tel3=t2.Phone3,
FROM Table1 t1
inner join Table2 t2
on
(t1.Tel1 = t2.Phone1 and t1.Tel1 is not null) or
(t1.Tel1 = t2.Phone2 and t1.Tel1 is not null) or
(t1.Tel1 = t2.Phone3 and t1.Tel1 is not null) or
(t1.Tel2 = t2.Phone1 and t1.Tel2 is not null) or
(t1.Tel2 = t2.Phone2 and t1.Tel2 is not null) or
(t1.Tel2 = t2.Phone3 and t1.Tel2 is not null) or
(t1.Tel3 = t2.Phone1 and t1.Tel3 is not null) or
(t1.Tel3 = t2.Phone2 and t1.Tel3 is not null) or
(t1.Tel3 = t2.Phone3 and t1.Tel3 is not null);
但是,此查询需要 30 多分钟才能运行。
执行计划表明,主要瓶颈是Table1 上的聚集索引扫描周围的Nested Loop。两个表的ID 列都有聚集索引。
由于我的 DBA 技能非常有限,任何人都可以提出提高此查询性能的最佳方法吗?将Tel1、Tel2 和Tel3 的索引添加到每一列是最好的做法,还是可以更改查询以提高性能?
【问题讨论】:
-
对两个表的 Tel1,Tel2,Tel3 应用非聚集索引
-
如果一个字段为空,那么
=将不会返回true - 你不需要所有这些and t1.Tel1 is not null。此外,您正在更新正在查询的字段,这可能会造成一些数据丢失(如果Tel1 = Phone2但Phone1为空)。首先尝试规范化电话号码(即有一个链接表来保存电话号码) -
你能添加一些测试数据吗(比如在 SQLFiddle 中)
-
全部排序; @Vishwajeet,根据以下答案拆分查询后,索引产生了影响。 @Keith,谢谢-当然,我知道
NULLs 不会被评估,它们只是为了生效:P
标签: sql sql-server-2008