2

19 列と約 4 億行の Composite-List-List パーティション テーブルがあります。週に 1 回、新しいデータがこのテーブルに挿入されます。挿入の前に、特定のパーティションに対して 2 つの列の値を null に設定する必要があります。

明白なアプローチは、COLUMN_1 がパーティション基準である次のようなものです。

UPDATE BLABLA_TABLE 
SET COLUMN_18 = NULL, SET COLUMN_19 = NULL 
WHERE COLUMN_1 IN (VALUE1, VALUE2…)

もちろん、これは非常に遅くなります。

2 番目に考えたのは、これら 2 つの列を null に設定する必要があるすべてのパーティションに CTAS を使用し、次に EXCHANGE PARTITION を使用して大きなテーブルのデータを更新することでした。残念ながら、これは複合パーティションであるため機能しません。

サブパーティションで同じアプローチを使用することもできますが、CATS を約 8000 回使用し、その後毎週それらのテーブルを削除する必要があります。それは今後のコードレビューに合格しないと思います。

誰かがこれを効率的に解決する別のアイデアを持っているかもしれませんか?

PS: データベースとして ORACLE 11g を使用しています。PPS: 下手な英語でごめんなさい…..

4

2 に答える 2

3

DDL (パーティションの切り替え) による更新を除外したため、DML のみを考慮することができます。

テーブルが非常に大きく分割されているため、実際にはそれほど悪い更新ではないと思います。更新を 8k のミニ更新 (それぞれが単一の小さなパーティション) に簡単に分割できます。

UPDATE BLABLA_TABLE SUBPARTITION (partition1) SET COLUMN_18 = NULL...

各サブパーティションには、更新される平均で 15,000 行が含まれるため、更新は比較的小さくなります。

これは依然として非常に大量の作業を表していますが、できればデータベース アクティビティが非常に少ない時間帯に、並列で実行するように設定するのは簡単です。また、個々の更新は、そのうちの 1 つが失敗した場合 (行がロックされた場合) に簡単に再開できますが、120M の更新では、エラーが発生した場合にロールバックに非常に長い時間がかかります。

于 2013-08-23T16:25:20.460 に答える
0

テーブル内の行のほぼ 90% を更新する場合、同じ構造の別のテーブルに挿入するだけの実現可能性/期間を確認します (やり直しが少ない、行の連鎖/移行がない、直接挿入によるキャッシュのバイパスなど)。インデックスを削除し、列を除外してターゲット テーブルで null のままにする)、テーブルの名前を変更してそれらを「交換」し、インデックスとトリガーを再構築してから、古いテーブルを削除します。

データ ウェアハウスでの私の経験から、単純な直接挿入は更新/削除よりも優れています。より多くの手順が必要ですが、全体的に短時間で完了します。テーブルの大部分を処理する必要がある場合、パーティション スワップは言うよりも簡単であり、ETL 開発者 (物理層にあるものにバインドされたロジック/アルゴリズム) にとってより複雑になります。実行する必要はありません。これまでのパーティションスワップ。

また、このテーブルを独自のテーブルスペースに分離し、これら2つのテーブルスペース間でストレージを交互に使用します(最初のテーブルから2番目のドロップテーブルに挿入し、次の実行ではその逆を行い、空のテーブルスペースのサイズを変更してスペースを再利用します)。

于 2014-04-07T10:06:12.490 に答える