我们的数据库中存储了一个程序,它通过连接30个列上的2个表并使用where条件来更新表。 SQL的格式为:
UPDATE Target
SET col1 = Source.col1
INNER JOIN Source
on
ISNULL(Target.Col2, '') = ISNULL(Source.Col2, '') and
ISNULL(Target.Col3, '') = ISNULL(Source.Col3, '') and
.
.
.
ISNULL(Target.Col31, '') = ISNULL(Source.Col31, '') and
这是查询计划。将其保存到您的PC并重新打开,以便更好地扩展。
Source表有65M记录,Target 165M。以前它曾经在很长一段时间内运行。考虑到查询的丑陋和潜在的低效率,我发现这令人惊讶。本月它运行了1.5个小时,使用了100%的处理器,我们不得不杀死它。
有任何建议如何即兴发布以下查询并使其按时运行..?
我们在30-col连接条件中使用的一些列上有单列索引。
我知道ISNULL函数和30列的连接是坚果,这是一个糟糕的设计。不要怪我,我继承了这种经济。
不幸的是,没有时间进行重新设计。有什么建议吗?
答案 0 :(得分:5)
INNER HASH JOIN
)。一旦我们有了确切的计划,我们就可以说更多。(A1 = A2 OR (A1 IS NULL AND A2 IS NULL))
。 SQL Server实际上识别此模式并在内部将其转换为“完全等于没有愚蠢的空语义”。即使使用空值,也可以通过这种方式查找索引。如果这没有用,请务必执行步骤(3)并在col2-col31上创建覆盖索引,包括col1。这将为您提供合并连接,这是本案例中最有效的计划。它真的很快。警告:这会使表的磁盘大小加倍并降低更新速度。
答案 1 :(得分:0)
DBa建议我们按照查询分析器的建议添加一个包含所有30列的索引,大多数是“包含”列。这允许查询完成。在我们运行的下个月,通常在1.5小时内运行的相同更新SQL在24小时内没有完成。当我们运行更新统计信息时,它在一小时内完成。