以下のデータベースの削除手法が表領域サイズに影響を与えるかどうかを尋ねたいと思います。データをクリアするための既存のコードには、以前は次のスタイルのコードがあります。
TRUNCATE TABLE WORK_T_TABLE;
INSERT /*APPEND*/ INTO WORK_T_TABLE
SELECT * FROM T_TABLE WHERE UPDATE_DATE > SYSDATE - 14;
TRUNCATE TABLE T_TABLE;
INSERT /*APPEND*/ INTO T_TABLE
SELECT * FROM WORK_T_TABLE;
不必要な切り捨てと挿入を行っていると思ったので、テーブルを単純な削除ステートメントに変更しました。
DELETE FROM T_TABLE WHERE UPDATE_DATE < SYSDATE - 14;
コードの削除は、オラクルで重要な意味がありますか?これにより、テーブルのセグメントサイズの不必要な増加が減少しますか?現在、SQLコードが変更されたため、データレコード数を変更せずにテーブルのセグメントサイズが急速に増加しています。
T_TABLEは常にデータを削除および挿入していることに注意してください。上記のdeleteコマンドを実行して、14日間のデータのみを保持します。次に、当日の新しいデータが挿入されます。テーブルのセグメントサイズは1か月以内に400%増加しましたが、レコード数は150%に増加しました。
テーブルのセグメントサイズとは、以下のコードの値から次の値を意味します。
SELECT BYTES FROM USER_SEGMENT WHERE SEGMENT_NAME = 'T_TABLE';
また、データは挿入選択を介して挿入されています。値は最初にsqlloaderを介してWORK_T_TABLEにロードされ、次に何らかの条件を介してテーブルに追加されます。
INSERT /*APPEND*/ INTO T_TABLE
SELECT * FROM WORK_T_TABLE;
注:ジャスティンの説明に対応するために、質問の文言をテーブルサイズからテーブルのセグメントサイズに変更しました。
「テーブルスペースサイズ」をどのように定義しますか?表領域を構成するディスク上のデータファイルの合計サイズに関心がありますか?または、テーブルスペースの一部であるすべてのセグメントの合計サイズに関心がありますか?
DELETE
を発行しても、テーブルのセグメントのサイズには影響しないため、どちらの定義でもテーブルスペースのサイズには影響しません。テーブルのセグメントのサイズとテーブルスペースのデータファイルのサイズはどちらも一定のままです。もちろん、テーブルのブロックの多くには、後続のINSERT
およびUPDATE
操作で使用できる追加の空き領域があります。
一方、TRUNCATE
を発行すると、テーブルのセグメントのサイズが小さくなります。これは、テーブルスペースのデータファイルのサイズには影響しません。ただし、表領域の一部であるすべてのセグメントの合計サイズに影響します。したがって、表領域のサイズの定義によっては違いがある場合があります。 DDLであるTRUNCATE
はトランザクションではないため、ロールバックできません。テーブル内の行の大部分を削除すると仮定すると、生成されるDELETE
とUNDO
がはるかに少ないため、REDO
を発行するよりもはるかに効率的である傾向があります。
最後の段落で、セグメントのサイズが新しいデータが追加される速度よりもはるかに速く増加していると述べている場合、新しい行は古い行とほぼ同じサイズであり、古い行はそうではないと仮定します。更新により時間の経過とともに増加しますが、新しい行がダイレクトパスインサートを介して追加されている可能性があります。ダイレクトパスインサートは常にセグメントの現在の最高水準点を超え、したがって、 DELETE
?もしそうなら、それは意図的ですか?テーブルが小さい場合、エクステント割り当ての粒度のために同様の違いが見られる場合があります。新しいエクステントを必要とせずに100行を挿入し、101番目の挿入ではOracleに新しいエクステントを割り当てる必要があり、その新しいエクステントで十分な場合があります。何千もの新しい行が追加されますが、セグメントのサイズは101番目の挿入後にのみ変更されます。ただし、特に大きなエクステントサイズを選択しない限り、これが適度に大きなテーブルである場合は、その可能性は低くなります。