如何从Oracle大表中删除多行



我们有一个大约3.8亿条记录的大表。我们需要删除超过2013年1月1日的前2.5亿条记录。我用谷歌搜索了一些方法,但我不满意。最常见和最快的方式是这样的:

create table newbig_table unrecoverable as
select * from oldhuge_table
where <condition is reverse of delete condition>

最后将新表重命名为原名称,但连续插入的新记录将是什么?

主要问题是;该表是一个在线表,由许多代理使用。所以我需要通过不减慢系统速度和不影响新记录来删除。我自己试过这个方法:

using (SqlConnection connData = new SqlConnection("Data Source=xxx;User ID=xxx;password=xxx;Initial Catalog=xxx"))
            {
                connData.Open();
                int cnt = 0;
                long total = 0;
                long startID = 1039142601;
                long endID = 1385795368;
                long recCount = endID  - startID;
                cnt++;
                long delRange = 400; //deletes 400 by 400
                for (long i = 1; i < endID; i++)
                {                        
                    startTime = DateTime.Now;
                    string deleteSql = "delete from DivaSessionFlowLog  " +
                                    " where ID >= " + startID.ToString() +
                                    " and ID <= " + (startID + delRange).ToString();
                    int strID = (int)((new SqlCommand(deleteSql, connData)).ExecuteNonQuery());
                    total = total + strID;
                    Console.WriteLine(i.ToString() + ":" + strID.ToString() + " OK DelCnt:" + total.ToString() + " ID:" + startID.ToString() + " Rest:" + String.Format("{0:#,#}", (recCount - total)) + " Time:" + DateTime.Now.ToString("HH':'mm':'ss"));
                    Thread.Sleep(200);
                    startID = startID + delRange;
                    i = startID;
                }

为了不使系统变慢,系统程序休眠200毫秒。但是,我计算的完成时间大约是2周。总之,我需要找到;

    快速
  • 不会使数据库变慢
  • 不影响连续插入的新记录

从一个大表中删除多行的方法。有什么建议吗?

最好的方法是对表进行分区,这样就可以删除旧的分区。

但是,如果您需要修改表,并且不要忘记表可能具有特权、索引、触发器等,并且您需要在整个过程中保持它可用,那么您需要使用DBMS_Redefinition。

同样,UNRECOVERABLE是旧的语法,但是您不会想要现代的等价语法,因为如果您在系统上发生媒体故障,您将丢失表和数据。

按日期对表进行分区将大有帮助。删除特定分区的内容要比逐个删除行快得多。

看看http://www.oracle-base.com/articles/misc/partitioning-an-existing-table.php;本文描述了如何从非分区表移动到分区表。

delRange从400改为40000或400000

根据我的计算,您的过程将在Thread.Sleep(200)中花费5.015天。并且有额外的时间用于网络,写入到控制台等。在块中修改数据并非总是可以避免的,但您至少应该尝试使用更大的块。

正如其他人提到的,分区可能非常有用。但是分区有很多缺点,如果这是一个罕见的过程,那么简单的方式可能是值得的。

相关内容

  • 没有找到相关文章

最新更新