web-dev-qa-db-ja.com

Oracleパーティションの分割中にデータが移動されるのはいつですか?

Oracleパーティションを分割する必要があり、分割を実行したときにOracleがデータを物理的に再配置するかどうかについて混乱しています。これが私がやろうとしていることです:

alter table SCHEMA.DATATABLE
   split partition MAXVAL_PART
   at (TO_DATE(' 2013-04-01 00:00:00',
               'SYYYY-MM-DD HH24:MI:SS',
               'NLS_CALENDAR=GREGORIAN'))
   into (partition PARTFOREXISTINGROWS
        tablespace EXISTINGMAXVALTABLESPACE,
         partition MAXVAL_PART
        tablespace NEWMAXVALTABLESPACE);

問題は、現在のMAXVAL_PARTに320 GBのデータが含まれており、このデータをディスク上に物理的に移動したくないことです。 2013-04-01でパーティションを切断すると、新しいパーティションにはデータがありませんが、それでもすべてのデータの移動が必要かどうかについて、矛盾する情報が表示されます。理想的には、オラクルは私の新しいMAXVALパーティションが空になることを確認し、それを新しいテーブルスペースで定義して、すべて完了です。

このコマンドはすでにディスク上にあるデータを移動しますか、それともそのままにして新しいパーティションを作成しますか?

この記事によると、Oracleは空のパーティションを検出して高速分割を行います http://docs.Oracle.com/cd/B19306_01/server.102/b14231/partiti.htm

しかし、分割によってすべてのデータが新しいストレージに移動されることを多くの場所で確認しています。どっち?

2
SqlRyan

データは移動されません。

テストケース:

SQL> CREATE TABLESPACE myts1 DATAFILE '/u01/app/Oracle/oradata/ORA112/myts1_01.dbf' size 50M;

Tablespace created.

SQL> CREATE TABLESPACE mytsmax DATAFILE '/u01/app/Oracle/oradata/ORA112/mytsmax_01.dbf' size 50M;

Tablespace created.

SQL> CREATE TABLE mytable (id NUMBER, dt DATE)
PARTITION BY RANGE (dt)
  (PARTITION mytablep1 VALUES LESS THAN (TO_DATE('2013-01-01', 'YYYY-MM-DD')) TABLESPACE myts1,
   PARTITION mytablep2 VALUES LESS THAN (TO_DATE('2013-02-01', 'YYYY-MM-DD')) TABLESPACE myts1,
   PARTITION mytablep3 VALUES LESS THAN (TO_DATE('2013-03-01', 'YYYY-MM-DD')) TABLESPACE myts1,
   PARTITION mytablep4 VALUES LESS THAN (MAXVALUE) TABLESPACE myts1
  );  

Table created.

データを挿入しました。結果:

SQL> select dt, count(*) 
  2  from mytable
  3  group by dt;

DT      COUNT(*)
--------- ----------
11-NOV-12     262272
11-JAN-13     262272
11-FEB-13     262272
11-MAR-13     262272

ここで、行が移動したかどうかを確認する最良の方法は、そのrowidを確認することです。特定の行のrowidは、データファイルおよびブロック内の行の場所に基づいています。したがって、rowidが変化した場合は、行が移動したことになります。 ドキュメントリンク

したがって、テーブル内の既存の行のROWIDを保持するテーブルを作成し、それらを挿入します。

SQL> create table myrowids ( r rowid );

Table created.

SQL> insert into myrowids ( select rowid from mytable );

1049088 rows created.

SQL> commit;

分割を実行します。

SQL> ALTER TABLE mytable
SPLIT PARTITION mytablep4
AT ( TO_DATE('2013-04-01', 'YYYY-MM-DD') )
INTO ( PARTITION mytablep4 TABLESPACE myts1, PARTITION mytablep5 TABLESPACE mytsmax );   

Table altered.

SQL>

行が移動していないことを確認します(代わりにEXISTSを使用した可能性があります)。

SQL> select count(*) from myrowids where r not in ( select rowid from mytable );

  COUNT(*)
----------
     0

SQL>

彼らはしていません!

5
Philᵀᴹ