我有一个带有12k地址记录的SQL Server 2008 R2数据库表,我试图过滤掉重复的电话号码并使用以下查询标记它们
SELECT a1.Id, a2.Id
FROM Addresses a1
INNER JOIN Addresses a2 ON a1.PhoneNumber = a2.PhoneNumber
WHERE a1.Id < a2.Id
注意:我意识到使用EXISTS
还有另一种解决此问题的方法,但这不是讨论的一部分。
该表在ID字段上有一个主键,带有聚簇索引,碎片级别为0,电话号码字段不为空,并且在12k记录中有大约130个重复。为了确保它不是服务器或数据库实例问题,我在4个不同的系统上运行它。
执行查询需要几分钟,有时需要几个小时。在尝试几乎所有内容作为我的最后一步之后,我删除了主键并在没有它的情况下运行查询,并且在1秒钟内执行它。我添加了主键,它仍然在一秒钟内运行。
有人知道造成这个问题的原因是什么吗?
主键是否可能以某种方式损坏?
编辑:道歉我在Sql查询中有一些拼写错误答案 0 :(得分:3)
超出数据统计。删除并重新创建PK将放弃新的统计数据。
现在太晚了,但我建议运行sp_updatestats来查看发生了什么。
如果您将数据库备份并还原到不同的系统,则统计信息将遵循数据
我怀疑在非索引(我猜)列PhoneNumber和CCAPhoneN
之后也有不同的计划答案 1 :(得分:2)
我猜测PhoneNumber
或PhoneNo
上没有索引。
您正在加入这些字段,但如果它们没有编入索引,则强制执行 TWO 表扫描,一个用于查询中表的每个实例,然后可能执行哈希匹配以查找匹配记录。
下一步 - 获取执行计划,看看痛点是什么。
然后,向这些字段添加索引(假设您看到了聚簇索引扫描)并查看是否修复了它。
我认为你的另一个问题是红鲱鱼。 PK可能与它无关,但你可能已经获得了页面缓存(你是否删除了缓冲区并清除了运行之间的缓存?),这使后来运行得更快。