1

私は、Oracle Exadata サーバーで最大 4,000 万行を処理する DWH 供給スクリプトに取り組んでいます。

次のテーブルがあります。

CREATE TABLE P.ARCHIVED_ID
(
    ID_ARCHIVED  VARCHAR2(31 BYTE) NOT NULL, -- CONSTRAINT UNIQUE / PRIMARY KEY
    IS_DELETE    CHAR(1 BYTE)      DEFAULT null
);

CREATE TABLE P.DWH_tableX
(
    ID      VARCHAR2(31 BYTE) NOT NULL, -- CONSTRAINT UNIQUE / PRIMARY KEY
    FIELD1  VARCHAR2(31 BYTE),
    FIELD2  VARCHAR2(31 BYTE),
    FIELD3  CHAR(2 BYTE),
    FIELD4  CHAR(1 BYTE)
);

ご覧のとおり、IS_DELETE設定できるフラグがYあります (デフォルトでは NULL です)。

これは、私があらゆるところで使用する必要がある標準的なクエリです:

SELECT 
    ID,
    FIELD1,
    FIELD2,
    FIELD3,
    FIELD4
FROM P.DWH_tableX A
WHERE EXISTS (
    SELECT 1 
    FROM P.ARCHIVED_ID B 
    WHERE 
        A.ID = B.ID_ARCHIVED 
        AND IS_DELETE = 'Y'
    );

質問、次のインデックスよりもこれを最適化するより良い方法はありますか?

CREATE BITMAP INDEX P.I_IS_DELETE 
    ON P.ARCHIVED_ID(IS_DELETE)
LOGGING
TABLESPACE TBS_P_01
NOPARALLEL;

さらにいくつかのポイント:

  • P.ARCHIVED_IDせずにアクセスすることはありませんWHERE IS_DELETE = 'Y'(または、スクリプトの最初でこのフィールドを更新するときに 1 回だけ)
  • NULLデフォルトでは、Oracle はインデックスに登録しないので、NULL代わりにを使用"N"して、部分的な="Y"ビットマップ インデックスを作成し、可能な限り小さく便利に保ちます。 間違い
  • オラクルが推奨するように(インデックスを使用する機能)EXISTS、代わりにを使用します。IN
  • の部分IS_DELETE = 'Y'は今のところ 0% ですが、DWH であるため、増加することが予想されます (新しい行はデータ ソースで毎日作成され、古い行は物理的に削除さIS_DELETE = 'Y'れ、DWH に設定されるため)
  • これWHERE EXISTSは、アーカイブされた値を凍結する方法であるため、私のスクリプトで約 20 回使用されます (それらを移動して、insert appendヒント付きで一時テーブルに戻します) 。
4

3 に答える 3

0

このクエリの場合:

SELECT ID, FIELD1, FIELD2, FIELD3, FIELD4
FROM P.DWH_tableX A
WHERE EXISTS (
    SELECT 1 
    FROM P.ARCHIVED_ID B 
    WHERE 
        A.ID = B.ID_ARCHIVED AND
        B.IS_DELETE = 'Y'
    );

インデックスについて最初に考えたのはARCHIVED_ID(ID_ARCHIVED, IS_DELETE). ビットマップ インデックスのパフォーマンスが向上したかどうかを知ることは興味深いでしょう。

于 2017-04-30T00:11:46.990 に答える