比较主键时,SQL Server查询执行速度非常慢

时间:2011-07-01 13:07:23

标签: sql-server

我有一个带有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查询中有一些拼写错误

2 个答案:

答案 0 :(得分:3)

超出数据统计。删除并重新创建PK将放弃新的统计数据。

现在太晚了,但我建议运行sp_updatestats来查看发生了什么。

如果您将数据库备份并还原到不同的系统,则统计信息将遵循数据

我怀疑在非索引(我猜)列PhoneNumber和CCAPhoneN

之后也有不同的计划

答案 1 :(得分:2)

我猜测PhoneNumberPhoneNo上没有索引。

您正在加入这些字段,但如果它们没有编入索引,则强制执行 TWO 表扫描,一个用于查询中表的每个实例,然后可能执行哈希匹配以查找匹配记录。

下一步 - 获取执行计划,看看痛点是什么。

然后,向这些字段添加索引(假设您看到了聚簇索引扫描)并查看是否修复了它。

我认为你的另一个问题是红鲱鱼。 PK可能与它无关,但你可能已经获得了页面缓存(你是否删除了缓冲区并清除了运行之间的缓存?),这使后来运行得更快。