-1

約 3 億 8000 万レコードの大きなテーブルがあります。2013 年 1 月 1 日より古い最初の 2 億 5000 万件のレコードを削除する必要があります。一般的で最速の方法は次のようになります。

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

delRange400 から 40000 または 400000 に変更します。

私の計算では、あなたのプロセスは で 5.015 日を費やしますThread.Sleep(200)。また、ネットワーク、コンソールへの書き込みなどのための余分な時間があります。チャンク内のデータを変更することは常に避けられるわけではありませんが、少なくともより大きなチャンクを使用するようにしてください。

他の人が述べたように、パーティショニングは非常に役立ちます。しかし、パーティショニングには多くの欠点があり、これがまれなプロセスである場合は、単純な方法で行う価値があるかもしれません.

于 2013-03-07T05:53:13.173 に答える
0

ここでは、テーブルを日付で分割すると非常に役立ちます。特定のパーティションの内容は、行を 1 つずつ削除するよりもはるかに迅速に削除できます。

http://www.oracle-base.com/articles/misc/partitioning-an-existing-table.phpをご覧ください。これは、パーティション化されていないテーブルからパーティション化されたテーブルに移動する方法を説明しています。

于 2013-03-06T21:27:32.870 に答える