-1

我们有一个大约 3.8 亿条记录的大表。我们需要删除前 2.5 亿条早于 2013 年 1 月 1 日的记录。我搜索了一些方法,但并不满意。常见且最快的方式如下所示:

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 周的完成时间。总之,我需要找到;

  • 快速地
  • 不会减慢数据库速度
  • 不会持续影响新插入的记录

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

4

3 回答 3

1

最好的方法是对表进行分区,以便可以删除较旧的分区。

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

此外,UNRECOVERABLE 是旧语法,但您不会想要现代的等效语法,因为如果系统上出现媒体故障,您将丢失表和数据。

于 2013-03-06T11:49:38.667 回答
0

从 400更改delRange为 40000 或 400000。

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

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

于 2013-03-07T05:53:13.173 回答
0

按日期对表进行分区在这里会有很大帮助。删除特定分区的内容比逐行删除要快得多。

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

于 2013-03-06T21:27:32.870 回答