我正在开发一个 DWH 提供脚本,该脚本在 Oracle Exadata 服务器上处理约 40M 行。
我有以下表格:
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'
(或者只有在我在脚本开头更新此字段时),我将永远不会访问默认情况下,Oracle 不会错误的NULL
在索引中注册,所以我使用NULL
而不是"N"
,允许我创建部分="Y"
位图索引,尽可能保持它的小和有用。- 我使用
EXISTS
, 而不是IN
Oracle 推荐的(使用索引的能力), - 部分
IS_DELETE = 'Y'
现在为 0%,但由于它是 DWH,预计只会增加(因为每天在数据源中创建新行,而旧行被物理删除,将它们设置IS_DELETE = 'Y'
在 DWH 中) - 在
WHERE EXISTS
我的脚本中使用了大约 20 次,因为这是我们处理冻结存档值的方式(将它们移动并返回到临时表上,并带有insert append
提示)