【发布时间】:2013-11-20 20:31:59
【问题描述】:
几年前有人在工作中进行了此更新并且它有效,问题是在一个进程中多次调用它需要将近 5 个小时,这不是常规更新,表之间没有一对一的记录匹配,这会根据同一张表中的 parituclar 字段的累积 (SUM) 进行更新,并且事情会变得更加复杂,因为此 SUM 仅限于基于日期和另一个字段的特殊条件。
我认为这类似于(隐式)内部联接,没有 1 对 1 匹配,例如 ALL VS ALL,因此当表中有 7000 条记录时,这件事将处理 7000 * 7000 条记录,超过 5500 万,在我看来应该在这里使用游标,但现在我需要更快的速度,我认为游标不会让我到达那里。
我的问题是:有没有办法重写它并使其更快?注意那个 SUM 的条件,这不是一个容易看到的 UPDATE(至少对我来说)。
更多信息: CodCtaCorriente 和 CodCtaCorrienteMon 是该表上的主键,但正如我之前所说,这里无意进行 1 对 1 匹配,这就是为什么在查询中不使用此键的原因,CodCtaCorrienteMon 用于条件但不用作连接条件(在)。
UPDATE #POS SET SaldoDespuesEvento =
(SELECT SUM(Importe)
FROM #POS CTACTE2
WHERE CTACTE2.CodComitente = #POS.CodComitente
AND CTACTE2.CodMoneda = #POS.CodMoneda
AND CTACTE2.EstaAnulado = 0
AND (DATEDIFF(day, CTACTE2.FechaLiquidacion, #POS.FechaLiquidacion) > 0
OR
(DATEDIFF(day, CTACTE2.FechaLiquidacion, #POS.FechaLiquidacion) = 0
AND (#POS.CodCtaCorrienteMon >= CTACTE2.CodCtaCorrienteMon))))
WHERE #POS.EstaAnulado = 0 AND #POS.EsSaldoAnterior = 0
【问题讨论】:
-
您介意提供一张查询计划的图片吗?
-
表中有哪些索引?如果您也添加
CREATE TABLE语句会有所帮助。 -
我尝试为不同的字段添加索引,但变化不大,有趣的是:在 WHERE:#POS .CodCtaCorrienteMon >= CTACTE2.CodCtaCorrienteMon。 CodCtaCorrienteMon 是一个数字和增量字段,当内部查询中的记录在此字段中的值高于外部查询中记录中的相应字段时,此条件的原因是不影响记录(不要 SUM)。
-
表格总共有多少行,更新了多少行(即通过测试
#POS.EstaAnulado = 0 AND #POS.EsSaldoAnterior = 0)? -
我在上次测试中使用了 7000 条记录(并不总是相同),这取决于临时表的创建方式。几乎所有行都已更新,该过滤器不会排除许多行。你知道,我开始认为没有更好的方法可以做到这一点。
标签: sql sql-server sql-server-2005 group-by sql-server-2000