如何从一个巨大的表中选择记录并以块的形式插入到另一个表中

时间:2010-10-20 05:15:05

标签: copy sybase

Sybase问题:需要将huge_tbl表(6000万+记录)的column1(id)的选定值复制到相对较小的small_tbl表中。从huge_tbl中选择行的标准取决于column2值(mydate)。

huge_tbl:

  • id是huge_table的主键
  • mydate列是日期时间字段。
  • huge_tbl上有一个索引(mydate,id)。
  • huge_tbl除了id和mydate之外还有更多列。

small_tbl:

  • small_tbl有2列: 标识列是标识列 id2类似于huge_tbl的id

由于要插入的记录数量非常大,并且为了避免填满日志空间,因此使用set rowcount将插入分成块。

因此,下一次迭代必须从上一次迭代完成的位置开始。假设在第一次迭代中插入的最后一条记录的mydate值为“02/10/2010 09:00:00”。由于“set rowcount ###”,huge_tbl中可能有更多具有相同mydate值的记录未被选中。下一次迭代必须选择mydate值从“02/10/2010 09:00:00”开始的记录,但也应该过滤掉在上一次迭代中已经选择的记录。

我尝试了一些方法,但它或者以small_tbl中的重复记录结束,或者处理时间太长。

对此问题的任何指示都将不胜感激。

例如 - 以下方法耗时太长:

while (row_count > 0)
begin

insert into small_tbl(id2)
select id from huge_tbl where mydate between <date1> and <date2>
and 1 = case 
    when ((mydate = @last_max_mydate)
         and id > @last_max_id))
    then 1
    when (mydate > @last_max_mydate)
    then 1
    else 0

select @row_count = @@rowcount

select @last_max_identity = max(identity) from small_tbl
select @last_max_id2 = id2 from small_tbl where identity = @last_max_identity
select @last_max_mydate = mydate from huge_tbl where id = @last_max_id2

end

4 个答案:

答案 0 :(得分:1)

这个问题易于解决,已经完成了一千次。

首先,如果你不介意我这么说,那你的解决方案太深入了,而你的桌子,你看不出问题是什么。所以请回答我的问题而不必担心他们的意思或意图。

1忘记huge_table上的IDENTITY列,或者定义PRIMARY KEY约束的是什么,真正的关系主键是什么?如果您不确定,请发布huge_table的所有显式和CREATE INDEX语句。

2将huge_table复制到small_table的目的是什么?每当您复制数据(甚至是临时的)时,都会出现一个未被识别的较大问题;如果你解决了这个问题,就会消除复制的需要。

回答您的答案

必定会有一些误解。您已提供该信息是您的原始帖子。对不起,但我特别问,你的OP中有什么是真正的逻辑键,不是PK 。为了识别欺骗,我需要知道数据。 Id PK意味着什么。你已经在使用它了。并得到欺骗。如果我使用它,我也会得到欺骗。因此我不会用它。因此,我需要知道表,数据,列,逻辑键是什么,(减去Id列)使每行唯一。

  • 如果你能提供整个表DDL(CREATE TABLE加上所有CREATE INDEX sttmts),那将是最好的。如果您需要保密,请更改表名。

  • 如果没有,那么我需要一个声明,一个描述,以及哪些列使每一行都是唯一的(Id列除外)。

  • 或sttmt,表示没有唯一标识符,在这种情况下,它不是关系表,在这种情况下,无法识别欺骗。

答案 1 :(得分:0)

create table as select语句不填充数据库日志。 尝试使用这一种方法而不是rowcount split。

答案 2 :(得分:0)

以下是您的问题的答案:

  • id是huge_tbl的主键。 (mydate,id)的索引存在。

标识列存在于small_tbl上,是主键。

  • 将部分数据从huge_tbl复制到small_tbl的目的有点复杂,无法解释。我只能说,来自huge_tbl的部分数据存储在small_tbl中以供进一步处理。

答案 3 :(得分:0)

使用sqsh。显然这个答案太短了,不允许我发帖,所以我再说一遍,使用sqsh。