問題
巨大なテーブルhaystack
が3 TB近くあり、月ごとにパーティション化され(date
)、client
によってサブパーティション化されています。列needle
によるクエリを容易にするために、すべてのクライアントにまたがるグローバルインデックスを作成する必要があります。これは非常に簡単です。
この問題は、最も古いテーブルパーティションが削除された月末に発生します。 3 TB=テーブルで毎月グローバルインデックスを再構築する余裕はありません。haystack
の最近の4つのパーティションのみが、常にデータベースにあります。したがって、月次パーティションを削除すると、テーブルの約25%が削除されます。
試行されたソリューション
needle
のハッシュによってグローバルパーティション化された列needle
にインデックスを作成しようとしました。ただし、これは、テーブルから古い月のパーティションを削除するときに、グローバルインデックス全体を再構築する必要があることを意味します。駄目だ。
また、列のインデックス(date
、needle
)を作成しました。これは、date
の範囲によってグローバルにパーティション化され、テーブルの毎月のパーティションと一致する範囲を持ちます。しかし、繰り返しになりますが、テーブルとインデックスがまったく同じようにパーティション化されていても(テーブルのサブパーティションを除いて)、テーブルから古い月のパーティションを削除すると、グローバルインデックス全体を更新する必要があります。
もちろん、ローカルパーティションインデックスを単純に作成することはできません。パーティションはローカルである必要がありますが、サブパーティションはありません。私が言えることから、それは不可能です。これは、インデックスのローカルパーティション分割オプションの全か無かの選択です。
パーティションの削除
完全を期すために、月末に古いパーティションを削除するために私が試したいくつかのオプションがあります...
alter table HAYSTACK drop partition P_MONTH update global indexes;
これは、ドロップ中にグローバルインデックスを維持しようとするため、時間がかかりすぎます。
alter table HAYSTACK drop partition P_MONTH;
グローバルインデックス句がないと、グローバルインデックスにすべてのパーティションが使用不可とマークされたままになります。 (当然のことながら。)
alter index HAYSTACK_IDX drop partition P_MONTH;
インデックスパーティションを削除すると、削除されたパーティションよりも高い値のパーティションが無効になります。ここでテーブルパーティションを削除するとしたら、グローバルインデックス全体を再構築する必要があります。
私の質問
グローバルインデックスパーティションを無効化または再構築せずに古いテーブルパーティションを削除できる方法はありますか?基本的に、これらのグローバルインデックスパーティションをローカルであるかのように処理するようにOracleに指示できますか? (悲しいことに、私の研究はノーと言っています。)
または...私の問題を解決する別の(より良い)方法はありますか?
バージョン<= 11.2?番号。*
しかし12cには、 非同期グローバルインデックスメンテナンス と呼ばれる新機能があります。
DROP PARTITION
操作はすぐに完了し、グローバルインデックスは使用可能な状態のままになります。トリックは、インデックスエントリが維持されず、それらがorphanedことであり、これらの孤立したエントリは後でクリーンアップされます。クリーンアッププロセスは、メンテナンスウィンドウで自動的に行われるか、手動で開始できます。
この詳細: https://richardfoote.wordpress.com/category/asynchronous-global-index-maintenance/
*:ありますが、あなたのケースには当てはまらないと思います。削除する前にパーティションからすべての行を削除(切り捨てない)すると、グローバルインデックスは使用可能な状態になります。しかし、これは3 TBテーブルの25%に相当な追加作業です。