私は、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ヒント付きで一時テーブルに戻します) 。