1

我有一些数据的“版本控制”表,每个版本有 150 万行,结构是:

[ID] bigint,
[version] int,
[somecolumn] int,
[anothercolumn] int,
[thirdcolumn] tinyint

而且我经常需要将一个版本复制到另一个版本中,就像这个查询一样:

INSERT INTO myTable 
    (SELECT ID, version + 1, somecolumn, anothercolumn, thirdcolumn 
     FROM myTable 
     WHERE version = @version)

但问题是这执行起来很慢,比如每次操作超过 10 秒。使此操作像闪电一样快的最佳方法是什么?我已经尝试选择一个临时表并从那里合并,但这并没有更快..

4

3 回答 3

1

一些想法:

  1. 使用临时表不太可能有帮助。那将是魔术。
  2. 使用 NOLOCK 不太可能有帮助。我看不到任何证据表明这是一个阻塞问题,因为只有一个并发事务(至少在测试系统上)。
  3. 不知道为什么重建索引比维护它更快。您的表中可能只有很少的版本?如果你得到很多索引重建将会变得越来越慢。不是长久之计。
  4. 尝试将聚集索引键更改为 (Version, ID) 以便插入是顺序的。随机 DML 比顺序 DML 慢得多。
于 2012-08-14T09:20:48.487 回答
0

您是否在版本列中添加了索引?那应该加快速度。

CREATE INDEX IDX_tableName_VERSION ON tableName (version)

更新

在读取的表上使用 NOLOCK 怎么样?如果您认为您可以从针对该表的其他事务在您的系统中获得脏读,则无效。我以前使用过这个成功,只是需要小心使用它!

INSERT INTO myTable 
    (SELECT ID, version + 1, somecolumn, anothercolumn, thirdcolumn 
     FROM myTable WITH(NOLOCK)
     WHERE version = @version)
于 2012-08-14T07:37:34.283 回答
0

看看这是否有效。

begin
  SELECT ID, version + 1, somecolumn, anothercolumn, thirdcolumn 
  into #temp
  FROM myTable 
  WHERE version = @version

  ALTER INDEX IDX_tableName_VERSION ON tableName.version DISABLE 

  INSERT INTO myTable
  select * from #temp

  ALTER INDEX IDX_tableName_VERSION ON tableName.version ENABLE 

end
于 2012-08-14T08:18:18.570 回答