sql >> データベース >  >> RDS >> Oracle

高速分割パーティショニング

    一部のアプリケーションログ用にパーティション化されたテーブルがあります。数年前、私は月に1つのパーティションでテーブルをパーティション化しました。 2016年が近づくにつれ、新年に向けてパーティションを追加する時期が来ました。パーティションテーブルには、最後の2つのパーティションとして、2015年12月のパーティションとMAXVALUEを使用するパーティションがあります。 MAXVALUEパーティションにデータを入れる予定はありません。 SPLITPARTITIONの操作を簡単にするためだけにあります。

    以前は、次のようなコマンドでパーティションを追加していました。

    ALTER TABLE usage_tracking
    SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS))
    INTO (PARTITION usage_tracking_p201601, PARTITION usage_tracking_pmax);
    ALTER TABLE usage_tracking
    SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS'))
    INTO (PARTITION usage_tracking_p201602, PARTITION usage_tracking_pmax);

    上記のSQLステートメントは、MAXVALUEパーティションを2つのパーティションに分割します。そのようなコマンドは12あり、毎月1つです。

    今年、非実稼働環境で2016年のスクリプトを実行しようとしたとき、これらのコマンドが完了するまでに約30分かかることに驚きました。以前は、数秒で完了しました。 USAGE_TRACKING_PMAXは空であるため、データを適切なパーティションに移動する必要はありません。

    SPLITを実行しているセッションのアクティビティを分析すると、このパーティションテーブルに追跡されたdbファイル待機イベントを明確に確認できました。空であるにもかかわらず、SPLIT操作が最大パーティションを読み取っていることは明らかでした。

    以前は問題なく機能していましたが、このデータベースは最近Oracle12cにアップグレードされました。高速分割パーティション操作を実行する方法に関する情報をMOSNote1268714.1で見つけました。これは、Oracle 10.2.0.3以降に適用されると書かれていますが、11.2.0.4では問題はありませんでした。それはおそらく運が悪かっただけで、私のすべてがアップグレードされたので、これをチェックするための11gデータベースがありません。そのため、何が変わったかに焦点を当てるのではなく、問題に対処して1日を続けます。

    MOSのメモによると、この空のパーティションで高速分割パーティションを実行するには、空のパーティションに統計があることを確認する必要があります。

    この空のパーティションのNUM_ROWSが0であることを確認しました。そのため、パーティションの統計を計算する必要はありませんでした。私の最初のSPLITPARTITION操作は非常に速く、ほんの数秒でした。パーティションは空であり、Oracleはそれを認識していました。私が驚いたのは、新しいパーティションUSAGE_TRACKING_P201601とUSAGE_TRACKING_PMAXが統計のためにNULL値になったことです。これは、2番目の新しいパーティションに対してSPLITPARTITION操作を実行するのに長い時間がかかることを意味しました。これが私の言いたいことの例です。まず、最大値パーティションに0行が表示されます。

    SQL> select num_rows from dba_tab_partitions
      2  where partition_name='USAGE_TRACKING_PMAX';
     
      NUM_ROWS
    ----------
             0

    次に、そのパーティションを分割します。

    SQL> ALTER TABLE usage_tracking
      2  SPLIT PARTITION usage_tracking_pmax AT ( TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') )
      3  INTO (PARTITION usage_tracking_p201601, PARTITION usage_tracking_pmax);
     
    Table altered.
    Elapsed: 00:00:03.13

    最後の2つのパーティションに統計がないことに注意してください。

    SQL> select num_rows from dba_tab_partitions
      2  where partition_name='USAGE_TRACKING_PMAX';
     
      NUM_ROWS
    ----------
     
     
    SQL> select num_rows from dba_tab_partitions
      2  where partition_name='USAGE_TRACKING_P201601';
     
      NUM_ROWS
    ----------
     
     

    統計がない場合、2016年2月のパーティションを作成するための次の分割パーティションには長い時間がかかります。

    SQL> ALTER TABLE nau_system.usage_tracking
      2  SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS'))
      3  INTO (PARTITION usage_tracking_p201602, PARTITION usage_tracking_pmax);
     
    Table altered.
    Elapsed: 00:27:41.09

    MOSノートに記載されているように、高速分割操作を実行するには、パーティションの統計が必要です。解決策は、パーティションの統計を計算してから、1つのALTERTABLEコマンドを使用してすべてのパーティションを一度に作成することです。

    BEGIN
     DBMS_STATS.gather_table_stats (tabname=>'USAGE_TRACKING',
     partname => 'USAGE_TRACKING_PMAX',
     granularity => 'PARTITION');
     END;
     /
    ALTER TABLE usage_tracking
    SPLIT PARTITION usage_tracking_pmax INTO
     (PARTITION usage_tracking_p201601 VALUES LESS THAN (TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
      PARTITION usage_tracking_p201602 VALUES LESS THAN (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
      PARTITION usage_tracking_p201603 VALUES LESS THAN (TO_DATE('04/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
      PARTITION usage_tracking_p201604 VALUES LESS THAN (TO_DATE('05/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
      PARTITION usage_tracking_p201605 VALUES LESS THAN (TO_DATE('06/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
      PARTITION usage_tracking_p201606 VALUES LESS THAN (TO_DATE('07/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
      PARTITION usage_tracking_p201607 VALUES LESS THAN (TO_DATE('08/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
      PARTITION usage_tracking_p201608 VALUES LESS THAN (TO_DATE('09/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
      PARTITION usage_tracking_p201609 VALUES LESS THAN (TO_DATE('10/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
      PARTITION usage_tracking_p201610 VALUES LESS THAN (TO_DATE('11/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
      PARTITION usage_tracking_p201611 VALUES LESS THAN (TO_DATE('12/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
      PARTITION usage_tracking_p201612 VALUES LESS THAN (TO_DATE('01/01/2017 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
      PARTITION usage_tracking_pmax);

    スクリプトを12個の個別のSPLITPARTITION操作の実行に任せた場合、各操作間の最大パーティションの統計を再計算する必要があります。 1つのコマンドを使用する方が効率的でした。


    1. OracleのJoinクエリで更新

    2. JDBCで開いている接続をプログラムでチェックする

    3. PL /Java1.5.2をPostgreSQL11にインストールします

    4. SQLServerのテキスト型とvarcharデータ型