【问题标题】:SQL Server with bulk update avoiding Cursor具有批量更新避免游标的 SQL Server
【发布时间】:2013-01-24 21:58:34
【问题描述】:

我想避免光标的性能问题。 我要解决的问题是: 使用由 UDF 计算的结果更新 Main 表中每条记录(大约 6000000 条)上的列 (VARCHAR )(通过使用一个更新语句),该 UDF 本身应该更新另一个 Counter 表中的计数器。
- 问题是 UDF 不能更新 Countertable,因为它是一个副作用。 - 由于 READONLY 标志,它也不能更新临时表或变量表。 - 我在主表上使用了一个更新触发器,但该触发器由一个更新语句触发一次,该语句存储在一个名为 insert 的表中。

我选择的解决方案是使用光标,如下所示。

  1. 从主表创建一个游标。
  2. 获取第一行
  3. 从计数器表中获取计数器
  4. 计数器++
  5. 调用 PROC 来计算结果、计数器等
  6. 用 PROC 的结果更新主表
  7. 更新计数器表
  8. 获取另一行

但相信我,大约 125 小时太慢了(不可能)。

有谁能帮帮我吗?

【问题讨论】:

  • 您能说得更具体些吗?你的表结构是什么,你想更新什么?
  • 我正在计算计数器表中的主表记录,然后将该计数器存储在主表中。谢谢。
  • 为什么将计数器存储在主表中?
  • 显示行的顺序。计数器是日期,它显示当年的顺序。
  • +1 墓碑。一般来说 - 不要在数据库中存储您可以从已经存储的内容中计算出的内容(在合理的时间内)。

标签: sql-server performance cursor updating


【解决方案1】:

我假设您的主表中有另一列标识该行,否则计数器将没有多大意义。

你可以试试这个吗?如果我正确理解了您的问题,则不需要函数或光标。只是一个临时表,因为你不能同时读取和更新一个表。

INSERT INTO tmpTable
SELECT
yourPrimaryKey, sex, YEAR(dob) AS dobyear, ROW_NUMBER() OVER (PARTITION BY YEAR(dob) ORDER BY dob) AS counter
FROM
mainTable;

UPDATE mainTable
SET code = CONCAT(tmpTable.sex, tmpTable.dobyear, counter)
FROM
mainTable
INNER JOIN tmpTable
ON mainTable.yourPrimaryKey = tmpTable.yourPrimaryKey;

它没有经过测试,请原谅任何语法错误或其他任何东西。

【讨论】:

  • 非常感谢,对我帮助很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多